From 426563ca45cc494777ab785c9d3159389721d97d Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 9 Aug 2022 17:00:17 +0300 Subject: [PATCH 01/10] feat: AuthManager -> Guard/Notary registry --- .../contracts/contracts/auth/AuthManager.sol | 63 ------------------- .../registry/AbstractGuardRegistry.sol | 14 +++++ .../registry/AbstractNotaryRegistry.sol | 35 +++++++++++ 3 files changed, 49 insertions(+), 63 deletions(-) delete mode 100644 packages/contracts/contracts/auth/AuthManager.sol create mode 100644 packages/contracts/contracts/registry/AbstractGuardRegistry.sol create mode 100644 packages/contracts/contracts/registry/AbstractNotaryRegistry.sol diff --git a/packages/contracts/contracts/auth/AuthManager.sol b/packages/contracts/contracts/auth/AuthManager.sol deleted file mode 100644 index 8301df76c0..0000000000 --- a/packages/contracts/contracts/auth/AuthManager.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.13; - -import { TypedMemView } from "../libs/TypedMemView.sol"; -import { Attestation } from "../libs/Attestation.sol"; -import { Auth } from "../libs/Auth.sol"; - -abstract contract AuthManager { - /*╔══════════════════════════════════════════════════════════════════════╗*\ - ▏*║ LIBRARIES ║*▕ - \*╚══════════════════════════════════════════════════════════════════════╝*/ - - using Attestation for bytes29; - using TypedMemView for bytes; - using TypedMemView for bytes29; - - /*╔══════════════════════════════════════════════════════════════════════╗*\ - ▏*║ UPGRADE GAP ║*▕ - \*╚══════════════════════════════════════════════════════════════════════╝*/ - - uint256[50] private __GAP; - - /*╔══════════════════════════════════════════════════════════════════════╗*\ - ▏*║ INTERNAL FUNCTIONS ║*▕ - \*╚══════════════════════════════════════════════════════════════════════╝*/ - - /** - * @notice Checks if the passed payload is a valid Attestation message, - * if the signature is valid and if the signer is an authorized updater. - * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise. - * @return _updater Updater that signed the Attestation - * @return _view Memory view on attestation - */ - function _checkUpdaterAuth(bytes memory _attestation) - internal - view - returns (address _updater, bytes29 _view) - { - _view = _attestation.ref(0); - require(_view.isAttestation(), "Not an attestation"); - _updater = Auth.recoverSigner( - _view.attestationData(), - _view.attestationSignature().clone() - ); - require(_isUpdater(_view.attestationDomain(), _updater), "Signer is not an updater"); - } - - function _checkWatchtowerAuth(bytes memory _report) - internal - view - returns (address _watchtower, bytes29 _data) - { - // TODO: check if _report is valid, once watchtower message standard is finalized - } - - /*╔══════════════════════════════════════════════════════════════════════╗*\ - ▏*║ VIRTUAL FUNCTIONS ║*▕ - \*╚══════════════════════════════════════════════════════════════════════╝*/ - - function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool); - - function _isWatchtower(address _watchtower) internal view virtual returns (bool); -} diff --git a/packages/contracts/contracts/registry/AbstractGuardRegistry.sol b/packages/contracts/contracts/registry/AbstractGuardRegistry.sol new file mode 100644 index 0000000000..fdcdea62d5 --- /dev/null +++ b/packages/contracts/contracts/registry/AbstractGuardRegistry.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +abstract contract AbstractGuardRegistry { + function _checkGuardAuth(bytes memory _report) + internal + view + returns (address _guard, bytes29 _data) + { + // TODO: check if _report is valid, once guard message standard is finalized + } + + function _isGuard(address _guard) internal view virtual returns (bool); +} diff --git a/packages/contracts/contracts/registry/AbstractNotaryRegistry.sol b/packages/contracts/contracts/registry/AbstractNotaryRegistry.sol new file mode 100644 index 0000000000..3b6537cd16 --- /dev/null +++ b/packages/contracts/contracts/registry/AbstractNotaryRegistry.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import { TypedMemView } from "../libs/TypedMemView.sol"; +import { Attestation } from "../libs/Attestation.sol"; +import { Auth } from "../libs/Auth.sol"; + +abstract contract AbstractNotaryRegistry { + using Attestation for bytes29; + using TypedMemView for bytes; + using TypedMemView for bytes29; + + /** + * @notice Checks if the passed payload is a valid Attestation message, + * if the signature is valid and if the signer is an authorized notary. + * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise. + * @return _updater Notary that signed the Attestation + * @return _view Memory view on attestation + */ + function _checkNotaryAuth(bytes memory _attestation) + internal + view + returns (address _updater, bytes29 _view) + { + _view = _attestation.ref(0); + require(_view.isAttestation(), "Not an attestation"); + _updater = Auth.recoverSigner( + _view.attestationData(), + _view.attestationSignature().clone() + ); + require(_isNotary(_view.attestationDomain(), _updater), "Signer is not a notary"); + } + + function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool); +} From b6899aeb9b71e76172a9561022e22b28444b76e7 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 9 Aug 2022 18:23:28 +0300 Subject: [PATCH 02/10] chore: NotaryRegistry becomes Global --- .../GlobalNotaryRegistry.sol} | 39 +++++++++++-------- ...istry.t.sol => GlobalNotaryRegistry.t.sol} | 8 ++-- ...ss.sol => GlobalNotaryRegistryHarness.sol} | 4 +- 3 files changed, 29 insertions(+), 22 deletions(-) rename packages/contracts/contracts/{NotaryRegistry.sol => registry/GlobalNotaryRegistry.sol} (88%) rename packages/contracts/test/{NotaryRegistry.t.sol => GlobalNotaryRegistry.t.sol} (92%) rename packages/contracts/test/harnesses/{NotaryRegistryHarness.sol => GlobalNotaryRegistryHarness.sol} (75%) diff --git a/packages/contracts/contracts/NotaryRegistry.sol b/packages/contracts/contracts/registry/GlobalNotaryRegistry.sol similarity index 88% rename from packages/contracts/contracts/NotaryRegistry.sol rename to packages/contracts/contracts/registry/GlobalNotaryRegistry.sol index 72c6fe644d..e76c77e4e6 100644 --- a/packages/contracts/contracts/NotaryRegistry.sol +++ b/packages/contracts/contracts/registry/GlobalNotaryRegistry.sol @@ -1,19 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; +import { AbstractNotaryRegistry } from "./AbstractNotaryRegistry.sol"; + /** + * @notice A Registry to keep track of Notaries on all domains. + * * @dev Modified OZ's EnumerableSet. This enables mapping into EnumerableSet. * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/structs/EnumerableSet.sol */ -contract NotaryRegistry { - /*╔══════════════════════════════════════════════════════════════════════╗*\ - ▏*║ EVENTS ║*▕ - \*╚══════════════════════════════════════════════════════════════════════╝*/ - - event NotaryAdded(uint32 indexed domain, address notary); - - event NotaryRemoved(uint32 indexed domain, address notary); - +contract GlobalNotaryRegistry is AbstractNotaryRegistry { /*╔══════════════════════════════════════════════════════════════════════╗*\ ▏*║ STORAGE ║*▕ \*╚══════════════════════════════════════════════════════════════════════╝*/ @@ -21,22 +17,28 @@ contract NotaryRegistry { // [domain => [notaries]] mapping(uint32 => address[]) internal domainNotaries; - // [domain => [notary => position in the above array plus 1]] (index 0 means notary is not in the array) + // [domain => [notary => position in the above array plus 1]] + // (index 0 means notary is not in the array) mapping(uint32 => mapping(address => uint256)) private notariesIndexes; /*╔══════════════════════════════════════════════════════════════════════╗*\ ▏*║ UPGRADE GAP ║*▕ \*╚══════════════════════════════════════════════════════════════════════╝*/ + // solhint-disable-next-line var-name-mixedcase uint256[48] private __GAP; /*╔══════════════════════════════════════════════════════════════════════╗*\ - ▏*║ INTERNAL FUNCTIONS ║*▕ + ▏*║ EVENTS ║*▕ \*╚══════════════════════════════════════════════════════════════════════╝*/ - function _isNotary(uint32 _domain, address _notary) internal view returns (bool) { - return notariesIndexes[_domain][_notary] != 0; - } + event NotaryAdded(uint32 indexed domain, address notary); + + event NotaryRemoved(uint32 indexed domain, address notary); + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ INTERNAL FUNCTIONS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ function _addNotary(uint32 _domain, address _notary) internal returns (bool) { if (_isNotary(_domain, _notary)) return false; @@ -49,8 +51,9 @@ contract NotaryRegistry { function _removeNotary(uint32 _domain, address _notary) internal returns (bool) { uint256 valueIndex = notariesIndexes[_domain][_notary]; if (valueIndex == 0) return false; - // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in - // the array, and then remove the last Notary (sometimes called as 'swap and pop'). + // To delete a Notary from the array in O(1), + // we swap the Notary to delete with the last one in the array, + // and then remove the last Notary (sometimes called as 'swap and pop'). address[] storage notaries = domainNotaries[_domain]; uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = notaries.length - 1; @@ -68,4 +71,8 @@ contract NotaryRegistry { emit NotaryRemoved(_domain, _notary); return true; } + + function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) { + return notariesIndexes[_domain][_notary] != 0; + } } diff --git a/packages/contracts/test/NotaryRegistry.t.sol b/packages/contracts/test/GlobalNotaryRegistry.t.sol similarity index 92% rename from packages/contracts/test/NotaryRegistry.t.sol rename to packages/contracts/test/GlobalNotaryRegistry.t.sol index 54644cae87..af80c3c9f9 100644 --- a/packages/contracts/test/NotaryRegistry.t.sol +++ b/packages/contracts/test/GlobalNotaryRegistry.t.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.13; import "forge-std/Test.sol"; -import { NotaryRegistryHarness } from "./harnesses/NotaryRegistryHarness.sol"; +import { GlobalNotaryRegistryHarness } from "./harnesses/GlobalNotaryRegistryHarness.sol"; -contract NotaryRegistryTest is Test { +contract GlobalNotaryRegistryTest is Test { event NotaryAdded(uint32 indexed domain, address notary); event NotaryRemoved(uint32 indexed domain, address notary); @@ -17,10 +17,10 @@ contract NotaryRegistryTest is Test { uint32 internal constant DOMAIN_1 = 1234; uint32 internal constant DOMAIN_2 = 4321; - NotaryRegistryHarness internal registry; + GlobalNotaryRegistryHarness internal registry; function setUp() public { - registry = new NotaryRegistryHarness(); + registry = new GlobalNotaryRegistryHarness(); } function test_addNotary_multipleDomains() public { diff --git a/packages/contracts/test/harnesses/NotaryRegistryHarness.sol b/packages/contracts/test/harnesses/GlobalNotaryRegistryHarness.sol similarity index 75% rename from packages/contracts/test/harnesses/NotaryRegistryHarness.sol rename to packages/contracts/test/harnesses/GlobalNotaryRegistryHarness.sol index 52811e9315..350fc4dc26 100644 --- a/packages/contracts/test/harnesses/NotaryRegistryHarness.sol +++ b/packages/contracts/test/harnesses/GlobalNotaryRegistryHarness.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.13; -import { NotaryRegistry } from "../../contracts/NotaryRegistry.sol"; +import { GlobalNotaryRegistry } from "../../contracts/registry/GlobalNotaryRegistry.sol"; -contract NotaryRegistryHarness is NotaryRegistry { +contract GlobalNotaryRegistryHarness is GlobalNotaryRegistry { function isNotary(uint32 _domain, address _notary) public view returns (bool) { return _isNotary(_domain, _notary); } From f8ac0bc74320c0d9853059fd37ddf4ef59f38e59 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 9 Aug 2022 18:25:30 +0300 Subject: [PATCH 03/10] feat: registry for domain's notaries --- .../registry/DomainNotaryRegistry.sol | 87 ++++++++++ .../contracts/test/DomainNotaryRegistry.t.sol | 149 ++++++++++++++++++ .../harnesses/DomainNotaryRegistryHarness.sol | 22 +++ 3 files changed, 258 insertions(+) create mode 100644 packages/contracts/contracts/registry/DomainNotaryRegistry.sol create mode 100644 packages/contracts/test/DomainNotaryRegistry.t.sol create mode 100644 packages/contracts/test/harnesses/DomainNotaryRegistryHarness.sol diff --git a/packages/contracts/contracts/registry/DomainNotaryRegistry.sol b/packages/contracts/contracts/registry/DomainNotaryRegistry.sol new file mode 100644 index 0000000000..75b7335c4a --- /dev/null +++ b/packages/contracts/contracts/registry/DomainNotaryRegistry.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import { AbstractNotaryRegistry } from "./AbstractNotaryRegistry.sol"; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +/** + * @notice A Registry to keep track of all Notaries on a single domain. + */ +contract DomainNotaryRegistry is AbstractNotaryRegistry { + using EnumerableSet for EnumerableSet.AddressSet; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ IMMUTABLES ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + uint32 private immutable trackedDomain; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ STORAGE ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + EnumerableSet.AddressSet internal notaries; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ UPGRADE GAP ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + // solhint-disable-next-line var-name-mixedcase + uint256[49] private __GAP; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ EVENTS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + event DomainNotaryAdded(address notary); + + event DomainNotaryRemoved(address notary); + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ CONSTRUCTOR ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + constructor(uint32 _trackedDomain) { + trackedDomain = _trackedDomain; + } + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ VIEWS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + function allNotaries() external view returns (address[] memory) { + return notaries.values(); + } + + function getNotary(uint256 _index) external view returns (address) { + return notaries.at(_index); + } + + function notariesAmount() external view returns (uint256) { + return notaries.length(); + } + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ INTERNAL FUNCTIONS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + function _addNotary(address _notary) internal returns (bool notaryAdded) { + notaryAdded = notaries.add(_notary); + if (notaryAdded) { + emit DomainNotaryAdded(_notary); + } + } + + function _removeNotary(address _notary) internal returns (bool notaryRemoved) { + notaryRemoved = notaries.remove(_notary); + if (notaryRemoved) { + emit DomainNotaryRemoved(_notary); + } + } + + function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) { + require(_domain == trackedDomain, "Wrong domain"); + return notaries.contains(_notary); + } +} diff --git a/packages/contracts/test/DomainNotaryRegistry.t.sol b/packages/contracts/test/DomainNotaryRegistry.t.sol new file mode 100644 index 0000000000..663edcf4c0 --- /dev/null +++ b/packages/contracts/test/DomainNotaryRegistry.t.sol @@ -0,0 +1,149 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import "forge-std/Test.sol"; + +import { DomainNotaryRegistryHarness } from "./harnesses/DomainNotaryRegistryHarness.sol"; + +contract DomainNotaryRegistryTest is Test { + DomainNotaryRegistryHarness internal registry; + + uint32 internal constant DOMAIN = 1000; + + address internal constant NOTARY_1 = address(1); + address internal constant NOTARY_2 = address(2); + address internal constant NOTARY_3 = address(3); + address internal constant NOTARY_4 = address(4); + + event DomainNotaryAdded(address notary); + event DomainNotaryRemoved(address notary); + + function setUp() public { + registry = new DomainNotaryRegistryHarness(DOMAIN); + } + + // solhint-disable func-name-mixedcase + function test_addNotary_multipleNotaries() public { + _checkAddNotary(NOTARY_1, true); + _checkAddNotary(NOTARY_2, true); + _checkAddNotary(NOTARY_3, true); + _checkAddNotary(NOTARY_4, true); + } + + function test_addNotary_twice() public { + test_addNotary_multipleNotaries(); + _checkAddNotary(NOTARY_1, false); + _checkAddNotary(NOTARY_2, false); + _checkAddNotary(NOTARY_3, false); + _checkAddNotary(NOTARY_4, false); + } + + function test_removeNotary() public { + test_addNotary_multipleNotaries(); + _checkRemoveNotary(NOTARY_3, true); + _checkRemoveNotary(NOTARY_1, true); + _checkRemoveNotary(NOTARY_4, true); + _checkRemoveNotary(NOTARY_2, true); + } + + function test_removeNotary_twice() public { + test_removeNotary(); + _checkRemoveNotary(NOTARY_3, false); + _checkRemoveNotary(NOTARY_1, false); + _checkRemoveNotary(NOTARY_4, false); + _checkRemoveNotary(NOTARY_2, false); + } + + function test_notariesAmount() public { + assertEq(registry.notariesAmount(), 0); + test_addNotary_multipleNotaries(); + assertEq(registry.notariesAmount(), 4); + _checkRemoveNotary(NOTARY_3, true); + assertEq(registry.notariesAmount(), 3); + _checkRemoveNotary(NOTARY_1, true); + assertEq(registry.notariesAmount(), 2); + _checkRemoveNotary(NOTARY_4, true); + assertEq(registry.notariesAmount(), 1); + _checkRemoveNotary(NOTARY_2, true); + assertEq(registry.notariesAmount(), 0); + } + + function test_getNotary() public { + test_addNotary_multipleNotaries(); + assertEq(registry.getNotary(0), NOTARY_1); + assertEq(registry.getNotary(1), NOTARY_2); + assertEq(registry.getNotary(2), NOTARY_3); + assertEq(registry.getNotary(3), NOTARY_4); + _checkRemoveNotary(NOTARY_3, true); + assertEq(registry.getNotary(0), NOTARY_1); + assertEq(registry.getNotary(1), NOTARY_2); + assertEq(registry.getNotary(2), NOTARY_4); + _checkRemoveNotary(NOTARY_1, true); + assertEq(registry.getNotary(0), NOTARY_4); + assertEq(registry.getNotary(1), NOTARY_2); + _checkRemoveNotary(NOTARY_4, true); + assertEq(registry.getNotary(0), NOTARY_2); + } + + function test_allNotaries() public { + test_addNotary_multipleNotaries(); + { + address[] memory notaries = registry.allNotaries(); + assertEq(notaries.length, 4); + assertEq(notaries[0], NOTARY_1); + assertEq(notaries[1], NOTARY_2); + assertEq(notaries[2], NOTARY_3); + assertEq(notaries[3], NOTARY_4); + } + _checkRemoveNotary(NOTARY_3, true); + { + address[] memory notaries = registry.allNotaries(); + assertEq(notaries.length, 3); + assertEq(notaries[0], NOTARY_1); + assertEq(notaries[1], NOTARY_2); + assertEq(notaries[2], NOTARY_4); + } + _checkRemoveNotary(NOTARY_1, true); + { + address[] memory notaries = registry.allNotaries(); + assertEq(notaries.length, 2); + assertEq(notaries[0], NOTARY_4); + assertEq(notaries[1], NOTARY_2); + } + _checkRemoveNotary(NOTARY_4, true); + { + address[] memory notaries = registry.allNotaries(); + assertEq(notaries.length, 1); + assertEq(notaries[0], NOTARY_2); + } + } + + function test_isNotary_notNotary() public { + _checkAddNotary(NOTARY_1, true); + assertFalse(registry.isNotary(DOMAIN, NOTARY_2)); + } + + function test_isNotary_wrongDomain() public { + _checkAddNotary(NOTARY_1, true); + vm.expectRevert("Wrong domain"); + registry.isNotary(DOMAIN + 1, NOTARY_1); + } + + function _checkAddNotary(address _notary, bool _added) internal { + if (_added) { + vm.expectEmit(true, true, true, true); + emit DomainNotaryAdded(_notary); + } + assertEq(registry.addNotary(_notary), _added); + assertTrue(registry.isNotary(DOMAIN, _notary)); + } + + function _checkRemoveNotary(address _notary, bool _removed) internal { + if (_removed) { + vm.expectEmit(true, true, true, true); + emit DomainNotaryRemoved(_notary); + } + assertEq(registry.removeNotary(_notary), _removed); + assertFalse(registry.isNotary(DOMAIN, _notary)); + } +} diff --git a/packages/contracts/test/harnesses/DomainNotaryRegistryHarness.sol b/packages/contracts/test/harnesses/DomainNotaryRegistryHarness.sol new file mode 100644 index 0000000000..179a27caeb --- /dev/null +++ b/packages/contracts/test/harnesses/DomainNotaryRegistryHarness.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.13; + +import { DomainNotaryRegistry } from "../../contracts/registry/DomainNotaryRegistry.sol"; + +contract DomainNotaryRegistryHarness is DomainNotaryRegistry { + // solhint-disable-next-line no-empty-blocks + constructor(uint32 _trackedDomain) DomainNotaryRegistry(_trackedDomain) {} + + function addNotary(address _notary) public returns (bool) { + return _addNotary(_notary); + } + + function removeNotary(address _notary) public returns (bool) { + return _removeNotary(_notary); + } + + function isNotary(uint32 _domain, address _notary) public view returns (bool) { + return _isNotary(_domain, _notary); + } +} From 74cfd24658a474e920efc2e02c2d12f9fd0cffe0 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 9 Aug 2022 18:25:44 +0300 Subject: [PATCH 04/10] feat: registry for all guards --- .../contracts/registry/GuardRegistry.sol | 72 +++++++++ packages/contracts/test/GuardRegistry.t.sol | 141 ++++++++++++++++++ .../test/harnesses/GuardRegistryHarness.sol | 19 +++ 3 files changed, 232 insertions(+) create mode 100644 packages/contracts/contracts/registry/GuardRegistry.sol create mode 100644 packages/contracts/test/GuardRegistry.t.sol create mode 100644 packages/contracts/test/harnesses/GuardRegistryHarness.sol diff --git a/packages/contracts/contracts/registry/GuardRegistry.sol b/packages/contracts/contracts/registry/GuardRegistry.sol new file mode 100644 index 0000000000..d297a013bd --- /dev/null +++ b/packages/contracts/contracts/registry/GuardRegistry.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import { AbstractGuardRegistry } from "./AbstractGuardRegistry.sol"; + +import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +/** + * @notice A Registry to keep track of all Guards. + */ +contract GuardRegistry is AbstractGuardRegistry { + using EnumerableSet for EnumerableSet.AddressSet; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ STORAGE ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + EnumerableSet.AddressSet internal guards; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ UPGRADE GAP ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + // solhint-disable-next-line var-name-mixedcase + uint256[49] private __GAP; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ EVENTS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + event GuardAdded(address guard); + + event GuardRemoved(address guard); + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ VIEWS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + function allGuards() external view returns (address[] memory) { + return guards.values(); + } + + function getGuard(uint256 _index) external view returns (address) { + return guards.at(_index); + } + + function guardsAmount() external view returns (uint256) { + return guards.length(); + } + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ INTERNAL FUNCTIONS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + function _addGuard(address _guard) internal returns (bool guardAdded) { + guardAdded = guards.add(_guard); + if (guardAdded) { + emit GuardAdded(_guard); + } + } + + function _removeGuard(address _guard) internal returns (bool guardRemoved) { + guardRemoved = guards.remove(_guard); + if (guardRemoved) { + emit GuardRemoved(_guard); + } + } + + function _isGuard(address _guard) internal view override returns (bool) { + return guards.contains(_guard); + } +} diff --git a/packages/contracts/test/GuardRegistry.t.sol b/packages/contracts/test/GuardRegistry.t.sol new file mode 100644 index 0000000000..0006c50743 --- /dev/null +++ b/packages/contracts/test/GuardRegistry.t.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import "forge-std/Test.sol"; + +import { GuardRegistryHarness } from "./harnesses/GuardRegistryHarness.sol"; + +contract GuardRegistryTest is Test { + GuardRegistryHarness internal registry; + + address internal constant GUARD_1 = address(1); + address internal constant GUARD_2 = address(2); + address internal constant GUARD_3 = address(3); + address internal constant GUARD_4 = address(4); + + event GuardAdded(address guard); + event GuardRemoved(address guard); + + function setUp() public { + registry = new GuardRegistryHarness(); + } + + // solhint-disable func-name-mixedcase + function test_addGuard_multipleGuards() public { + _checkAddGuard(GUARD_1, true); + _checkAddGuard(GUARD_2, true); + _checkAddGuard(GUARD_3, true); + _checkAddGuard(GUARD_4, true); + } + + function test_addGuard_twice() public { + test_addGuard_multipleGuards(); + _checkAddGuard(GUARD_1, false); + _checkAddGuard(GUARD_2, false); + _checkAddGuard(GUARD_3, false); + _checkAddGuard(GUARD_4, false); + } + + function test_removeGuard() public { + test_addGuard_multipleGuards(); + _checkRemoveGuard(GUARD_3, true); + _checkRemoveGuard(GUARD_1, true); + _checkRemoveGuard(GUARD_4, true); + _checkRemoveGuard(GUARD_2, true); + } + + function test_removeGuard_twice() public { + test_removeGuard(); + _checkRemoveGuard(GUARD_3, false); + _checkRemoveGuard(GUARD_1, false); + _checkRemoveGuard(GUARD_4, false); + _checkRemoveGuard(GUARD_2, false); + } + + function test_guardsAmount() public { + assertEq(registry.guardsAmount(), 0); + test_addGuard_multipleGuards(); + assertEq(registry.guardsAmount(), 4); + _checkRemoveGuard(GUARD_3, true); + assertEq(registry.guardsAmount(), 3); + _checkRemoveGuard(GUARD_1, true); + assertEq(registry.guardsAmount(), 2); + _checkRemoveGuard(GUARD_4, true); + assertEq(registry.guardsAmount(), 1); + _checkRemoveGuard(GUARD_2, true); + assertEq(registry.guardsAmount(), 0); + } + + function test_getGuard() public { + test_addGuard_multipleGuards(); + assertEq(registry.getGuard(0), GUARD_1); + assertEq(registry.getGuard(1), GUARD_2); + assertEq(registry.getGuard(2), GUARD_3); + assertEq(registry.getGuard(3), GUARD_4); + _checkRemoveGuard(GUARD_3, true); + assertEq(registry.getGuard(0), GUARD_1); + assertEq(registry.getGuard(1), GUARD_2); + assertEq(registry.getGuard(2), GUARD_4); + _checkRemoveGuard(GUARD_1, true); + assertEq(registry.getGuard(0), GUARD_4); + assertEq(registry.getGuard(1), GUARD_2); + _checkRemoveGuard(GUARD_4, true); + assertEq(registry.getGuard(0), GUARD_2); + } + + function test_isGuard_notGuard() public { + _checkAddGuard(GUARD_1, true); + assertFalse(registry.isGuard(GUARD_2)); + } + + function test_allGuards() public { + test_addGuard_multipleGuards(); + { + address[] memory guards = registry.allGuards(); + assertEq(guards.length, 4); + assertEq(guards[0], GUARD_1); + assertEq(guards[1], GUARD_2); + assertEq(guards[2], GUARD_3); + assertEq(guards[3], GUARD_4); + } + _checkRemoveGuard(GUARD_3, true); + { + address[] memory guards = registry.allGuards(); + assertEq(guards.length, 3); + assertEq(guards[0], GUARD_1); + assertEq(guards[1], GUARD_2); + assertEq(guards[2], GUARD_4); + } + _checkRemoveGuard(GUARD_1, true); + { + address[] memory guards = registry.allGuards(); + assertEq(guards.length, 2); + assertEq(guards[0], GUARD_4); + assertEq(guards[1], GUARD_2); + } + _checkRemoveGuard(GUARD_4, true); + { + address[] memory guards = registry.allGuards(); + assertEq(guards.length, 1); + assertEq(guards[0], GUARD_2); + } + } + + function _checkAddGuard(address _guard, bool _added) internal { + if (_added) { + vm.expectEmit(true, true, true, true); + emit GuardAdded(_guard); + } + assertEq(registry.addGuard(_guard), _added); + assertTrue(registry.isGuard(_guard)); + } + + function _checkRemoveGuard(address _guard, bool _removed) internal { + if (_removed) { + vm.expectEmit(true, true, true, true); + emit GuardRemoved(_guard); + } + assertEq(registry.removeGuard(_guard), _removed); + assertFalse(registry.isGuard(_guard)); + } +} diff --git a/packages/contracts/test/harnesses/GuardRegistryHarness.sol b/packages/contracts/test/harnesses/GuardRegistryHarness.sol new file mode 100644 index 0000000000..b9a8fc7ade --- /dev/null +++ b/packages/contracts/test/harnesses/GuardRegistryHarness.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.13; + +import { GuardRegistry } from "../../contracts/registry/GuardRegistry.sol"; + +contract GuardRegistryHarness is GuardRegistry { + function addGuard(address _guard) public returns (bool) { + return _addGuard(_guard); + } + + function removeGuard(address _guard) public returns (bool) { + return _removeGuard(_guard); + } + + function isGuard(address _guard) public view returns (bool) { + return _isGuard(_guard); + } +} From 6288de15facc0dc549304b4be730b62ccde68a6c Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 9 Aug 2022 18:26:22 +0300 Subject: [PATCH 05/10] fix: registries in AttestationCollector --- .../contracts/contracts/AttestationCollector.sol | 13 +++---------- packages/contracts/test/AttestationCollector.t.sol | 4 ++-- .../test/harnesses/AttestationCollectorHarness.sol | 6 +++--- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/contracts/contracts/AttestationCollector.sol b/packages/contracts/contracts/AttestationCollector.sol index c70971711b..127efe4040 100644 --- a/packages/contracts/contracts/AttestationCollector.sol +++ b/packages/contracts/contracts/AttestationCollector.sol @@ -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; @@ -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 @@ -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, diff --git a/packages/contracts/test/AttestationCollector.t.sol b/packages/contracts/test/AttestationCollector.t.sol index 228cfe3bd5..9dbac1a9c8 100644 --- a/packages/contracts/test/AttestationCollector.t.sol +++ b/packages/contracts/test/AttestationCollector.t.sol @@ -93,7 +93,7 @@ contract AttestationCollectorTest is SynapseTest { function test_submitAttestation_notUpdater() public { test_addNotary(); (bytes memory attestation, ) = signHomeAttestation(fakeUpdaterPK, nonce, root); - vm.expectRevert("Signer is not an updater"); + vm.expectRevert("Signer is not a notary"); collector.submitAttestation(attestation); } @@ -101,7 +101,7 @@ contract AttestationCollectorTest is SynapseTest { test_addNotary(); (bytes memory attestation, ) = signRemoteAttestation(updaterPK, nonce, root); // Signer is not set as updater for the `remoteDomain` - vm.expectRevert("Signer is not an updater"); + vm.expectRevert("Signer is not a notary"); collector.submitAttestation(attestation); } diff --git a/packages/contracts/test/harnesses/AttestationCollectorHarness.sol b/packages/contracts/test/harnesses/AttestationCollectorHarness.sol index 7c1b1f25a2..bbffb14dd2 100644 --- a/packages/contracts/test/harnesses/AttestationCollectorHarness.sol +++ b/packages/contracts/test/harnesses/AttestationCollectorHarness.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.13; import { AttestationCollector } from "../../contracts/AttestationCollector.sol"; contract AttestationCollectorHarness is AttestationCollector { - function isNotary(uint32 _domain, address _notary) public view returns (bool) { - return _isNotary(_domain, _notary); - } + function isNotary(uint32 _domain, address _notary) public view returns (bool) { + return _isNotary(_domain, _notary); + } } From 8e2c6fad862b6230856cece0a20cde6c6ce9a70c Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 9 Aug 2022 18:46:01 +0300 Subject: [PATCH 06/10] fix: registries in Home/ReplicaManager --- packages/contracts/contracts/Home.sol | 27 +++++++------------ .../contracts/contracts/ReplicaManager.sol | 16 ++++------- packages/contracts/test/ReplicaManager.t.sol | 3 ++- .../test/harnesses/ReplicaManagerHarness.sol | 4 +++ 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/packages/contracts/contracts/Home.sol b/packages/contracts/contracts/Home.sol index 53e5373474..af2da12ed3 100644 --- a/packages/contracts/contracts/Home.sol +++ b/packages/contracts/contracts/Home.sol @@ -4,7 +4,8 @@ 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"; @@ -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, UpdaterStorage, DomainNotaryRegistry, GuardRegistry { // ============ Libraries ============ using Attestation for bytes29; @@ -114,7 +115,10 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager { // ============ Constructor ============ - constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks + constructor(uint32 _localDomain) + UpdaterStorage(_localDomain) + DomainNotaryRegistry(_localDomain) + {} // solhint-disable-line no-empty-blocks // ============ Initializer ============ @@ -122,6 +126,7 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager { // initialize queue, set Updater Manager, and 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 historicalRoots.push(bytes32("")); @@ -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 _updater, bytes29 _view) = _checkNotaryAuth(_attestation); uint32 _nonce = _view.attestationNonce(); bytes32 _root = _view.attestationRoot(); // Check if nonce is valid, if not => update is fraud @@ -315,20 +320,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. diff --git a/packages/contracts/contracts/ReplicaManager.sol b/packages/contracts/contracts/ReplicaManager.sol index 680d5b8a59..86445e5970 100644 --- a/packages/contracts/contracts/ReplicaManager.sol +++ b/packages/contracts/contracts/ReplicaManager.sol @@ -3,7 +3,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"; @@ -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, UpdaterStorage, GlobalNotaryRegistry, GuardRegistry { // ============ Libraries ============ using ReplicaLib for ReplicaLib.Replica; @@ -95,6 +96,7 @@ contract ReplicaManager is Version0, UpdaterStorage, AuthManager { */ function initialize(uint32 _remoteDomain, address _updater) public initializer { __SynapseBase_initialize(_updater); + _addNotary(_remoteDomain, _updater); // set storage variables entered = 1; activeReplicas[_remoteDomain] = _createReplica(_remoteDomain); @@ -136,7 +138,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(); @@ -321,14 +323,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) { diff --git a/packages/contracts/test/ReplicaManager.t.sol b/packages/contracts/test/ReplicaManager.t.sol index 2431dc4308..e792aa31da 100644 --- a/packages/contracts/test/ReplicaManager.t.sol +++ b/packages/contracts/test/ReplicaManager.t.sol @@ -123,12 +123,13 @@ contract ReplicaManagerTest is SynapseTest { function test_updateWithFakeSigner() public { uint32 nonce = 42; (bytes memory attestation, ) = signRemoteAttestation(fakeUpdaterPK, nonce, ROOT); - vm.expectRevert("Signer is not an updater"); + vm.expectRevert("Signer is not a notary"); // Update signed by fakeUpdater should be rejected replicaManager.submitAttestation(attestation); } function test_updateWithLocalDomain() public { + replicaManager.addNotary(localDomain, updater); uint32 nonce = 42; (bytes memory attestation, ) = signHomeAttestation(updaterPK, nonce, ROOT); vm.expectRevert("Update refers to local chain"); diff --git a/packages/contracts/test/harnesses/ReplicaManagerHarness.sol b/packages/contracts/test/harnesses/ReplicaManagerHarness.sol index df5cfeb6c5..57366f3e9a 100644 --- a/packages/contracts/test/harnesses/ReplicaManagerHarness.sol +++ b/packages/contracts/test/harnesses/ReplicaManagerHarness.sol @@ -17,6 +17,10 @@ contract ReplicaManagerHarness is ReplicaManager { constructor(uint32 _localDomain) ReplicaManager(_localDomain) {} + function addNotary(uint32 _domain, address _notary) public { + _addNotary(_domain, _notary); + } + function setSensitiveValue(uint256 _newValue) external onlySystemMessenger { sensitiveValue = _newValue; } From d19d9cf3d72e5095ea2790c284ee806dc894ad1e Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 9 Aug 2022 19:23:48 +0300 Subject: [PATCH 07/10] feat: SystemContract --- packages/contracts/contracts/Home.sol | 23 ++-- .../contracts/contracts/ReplicaManager.sol | 30 +++-- .../contracts/contracts/UpdaterStorage.sol | 116 ------------------ .../contracts/system/SystemContract.sol | 77 ++++++++++++ 4 files changed, 111 insertions(+), 135 deletions(-) delete mode 100644 packages/contracts/contracts/UpdaterStorage.sol create mode 100644 packages/contracts/contracts/system/SystemContract.sol diff --git a/packages/contracts/contracts/Home.sol b/packages/contracts/contracts/Home.sol index af2da12ed3..c9edffda46 100644 --- a/packages/contracts/contracts/Home.sol +++ b/packages/contracts/contracts/Home.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.13; // ============ Internal Imports ============ import { Version0 } from "./Version0.sol"; -import { UpdaterStorage } from "./UpdaterStorage.sol"; import { DomainNotaryRegistry } from "./registry/DomainNotaryRegistry.sol"; import { GuardRegistry } from "./registry/GuardRegistry.sol"; import { Attestation } from "./libs/Attestation.sol"; @@ -12,6 +11,7 @@ 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"; @@ -28,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, DomainNotaryRegistry, GuardRegistry { +contract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry { // ============ Libraries ============ using Attestation for bytes29; @@ -116,16 +116,15 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, DomainNotaryRegist // ============ Constructor ============ constructor(uint32 _localDomain) - UpdaterStorage(_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 @@ -158,7 +157,8 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, DomainNotaryRegist * @param _updater the new Updater */ function setUpdater(address _updater) external onlyUpdaterManager { - _setUpdater(_updater); + // TODO: do this properly + _addNotary(_updater); // set the Home state to Active // now that Updater has been rotated state = States.Active; @@ -264,7 +264,7 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, DomainNotaryRegist */ function improperAttestation(bytes memory _attestation) public notFailed returns (bool) { // This will revert if signature is not valid - (address _updater, bytes29 _view) = _checkNotaryAuth(_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 @@ -275,8 +275,8 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, DomainNotaryRegist } // 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; } @@ -296,12 +296,13 @@ contract Home is Version0, MerkleTreeManager, UpdaterStorage, DomainNotaryRegist * @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 // set contract to FAILED state = States.Failed; // slash Updater updaterManager.slashUpdater(payable(msg.sender)); - emit UpdaterSlashed(updater, msg.sender); + emit UpdaterSlashed(_notary, msg.sender); } /** diff --git a/packages/contracts/contracts/ReplicaManager.sol b/packages/contracts/contracts/ReplicaManager.sol index 86445e5970..c2dc44929f 100644 --- a/packages/contracts/contracts/ReplicaManager.sol +++ b/packages/contracts/contracts/ReplicaManager.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.13; // ============ Internal Imports ============ -import { UpdaterStorage } from "./UpdaterStorage.sol"; import { GlobalNotaryRegistry } from "./registry/GlobalNotaryRegistry.sol"; import { GuardRegistry } from "./registry/GuardRegistry.sol"; import { Attestation } from "./libs/Attestation.sol"; @@ -14,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"; @@ -23,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, GlobalNotaryRegistry, GuardRegistry { +contract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry { // ============ Libraries ============ using ReplicaLib for ReplicaLib.Replica; @@ -77,9 +77,17 @@ contract ReplicaManager is Version0, UpdaterStorage, GlobalNotaryRegistry, Guard 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 ============ @@ -95,7 +103,7 @@ contract ReplicaManager is Version0, UpdaterStorage, GlobalNotaryRegistry, Guard * @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; @@ -148,7 +156,12 @@ contract ReplicaManager is Version0, UpdaterStorage, GlobalNotaryRegistry, Guard replica.setConfirmAt(newRoot, block.timestamp); // update nonce replica.setNonce(nonce); - emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone()); + emit AttestationAccepted( + remoteDomain, + nonce, + newRoot, + _view.attestationSignature().clone() + ); } /** @@ -156,7 +169,7 @@ contract ReplicaManager is Version0, UpdaterStorage, GlobalNotaryRegistry, Guard * `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 */ @@ -221,8 +234,9 @@ contract ReplicaManager is Version0, UpdaterStorage, GlobalNotaryRegistry, Guard * 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); } /** diff --git a/packages/contracts/contracts/UpdaterStorage.sol b/packages/contracts/contracts/UpdaterStorage.sol deleted file mode 100644 index ed944c6f13..0000000000 --- a/packages/contracts/contracts/UpdaterStorage.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.13; - -// ============ Internal Imports ============ -import { ISystemMessenger } from "./interfaces/ISystemMessenger.sol"; -import { Message } from "./libs/Message.sol"; -// ============ External Imports ============ -import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import { - OwnableUpgradeable -} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; - -/** - * @title UpdaterStorage - * @author Illusory Systems Inc. - * @notice Shared utilities between Home and Replica. - */ -abstract contract UpdaterStorage is Initializable, OwnableUpgradeable { - // ============ Immutable Variables ============ - - // Domain of chain on which the contract is deployed - uint32 public immutable localDomain; - - // ============ Public Variables ============ - - // Address of bonded Updater - address public updater; - - ISystemMessenger public systemMessenger; - - // ============ Upgrade Gap ============ - - // gap for upgrade safety - uint256[48] private __GAP; - - // ============ Events ============ - - /** - * @notice Emitted when update is made on Home - * or unconfirmed update root is submitted on Replica - * @param homeDomain Domain of home contract - * @param nonce Nonce of new merkle root - * @param root New merkle root - * @param signature Updater's signature on `homeDomain`, `nonce` and `root` - */ - // TODO: emit abi encoded update instead? - event Update( - uint32 indexed homeDomain, - uint32 indexed nonce, - bytes32 indexed root, - bytes signature - ); - - /** - * @notice Emitted when Updater is rotated - * @param oldUpdater The address of the old updater - * @param newUpdater The address of the new updater - */ - event NewUpdater(address oldUpdater, address newUpdater); - - // ============ Constructor ============ - - constructor(uint32 _localDomain) { - localDomain = _localDomain; - } - - // ============ Initializer ============ - - function __SynapseBase_initialize(address _updater) internal onlyInitializing { - __Ownable_init(); - _setUpdater(_updater); - } - - // ============ Modifiers ============ - - /** - * @dev Modifier for functions that are supposed to be called from - * System Contracts on other chains. - */ - modifier onlySystemMessenger() { - _assertSystemMessenger(); - _; - } - - // ============ Restricted Functions ============ - - function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner { - systemMessenger = _systemMessenger; - } - - // ============ Internal Functions ============ - - function _assertSystemMessenger() internal view { - require(msg.sender == address(systemMessenger), "!systemMessenger"); - } - - /** - * @notice Set the Updater - * @param _newUpdater Address of the new Updater - */ - function _setUpdater(address _newUpdater) internal { - address _oldUpdater = updater; - updater = _newUpdater; - emit NewUpdater(_oldUpdater, _newUpdater); - } - - /** - * @dev should be impossible to renounce ownership; - * we override OpenZeppelin OwnableUpgradeable's - * implementation of renounceOwnership to make it a no-op - */ - function renounceOwnership() public override onlyOwner { - // do nothing - } -} diff --git a/packages/contracts/contracts/system/SystemContract.sol b/packages/contracts/contracts/system/SystemContract.sol new file mode 100644 index 0000000000..41e1bd3e95 --- /dev/null +++ b/packages/contracts/contracts/system/SystemContract.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import { ISystemMessenger } from "../interfaces/ISystemMessenger.sol"; + +import { + OwnableUpgradeable +} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +/** + * @notice Shared utilities between Synapse System Contracts: Home, ReplicaManager, etc. + */ +abstract contract SystemContract is OwnableUpgradeable { + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ IMMUTABLES ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + uint32 public immutable localDomain; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ STORAGE ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + ISystemMessenger public systemMessenger; + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ CONSTRUCTOR ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + constructor(uint32 _localDomain) { + localDomain = _localDomain; + } + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ INITIALIZER ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + function __SystemContract_initialize() internal onlyInitializing { + __Ownable_init_unchained(); + } + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ MODIFIERS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + /** + * @dev Modifier for functions that are supposed to be called from + * System Contracts on other chains. + */ + modifier onlySystemMessenger() { + _assertSystemMessenger(); + _; + } + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ OWNER ONLY ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner { + systemMessenger = _systemMessenger; + } + + /** + * @dev Should be impossible to renounce ownership; + * we override OpenZeppelin OwnableUpgradeable's + * implementation of renounceOwnership to make it a no-op + */ + function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks + + /*╔══════════════════════════════════════════════════════════════════════╗*\ + ▏*║ INTERNAL FUNCTIONS ║*▕ + \*╚══════════════════════════════════════════════════════════════════════╝*/ + + function _assertSystemMessenger() internal view { + require(msg.sender == address(systemMessenger), "!systemMessenger"); + } +} From 7290885c47524238da84813c30760da9fee9e1f1 Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 9 Aug 2022 19:24:01 +0300 Subject: [PATCH 08/10] tests: adjust for latest changes --- packages/contracts/test/Home.t.sol | 8 ++++---- packages/contracts/test/ReplicaManager.t.sol | 16 ++++++++-------- packages/contracts/test/UpdaterManager.t.sol | 4 ++-- .../contracts/test/harnesses/HomeHarness.sol | 8 ++++++-- .../test/harnesses/ReplicaManagerHarness.sol | 4 ++++ 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/contracts/test/Home.t.sol b/packages/contracts/test/Home.t.sol index 7438b637dd..6880178ad2 100644 --- a/packages/contracts/test/Home.t.sol +++ b/packages/contracts/test/Home.t.sol @@ -30,7 +30,7 @@ contract HomeTest is SynapseTestWithUpdaterManager { assertEq(address(home.updaterManager()), address(updaterManager)); assertEq(home.owner(), address(this)); assertEq(uint256(home.state()), 1); - assertEq(home.updater(), updater); + assertTrue(home.isNotary(updater)); } function test_cannotInitializeTwice() public { @@ -44,10 +44,10 @@ contract HomeTest is SynapseTestWithUpdaterManager { } function test_setUpdater() public { - assertFalse(home.updater() == address(1337)); + assertFalse(home.isNotary(address(1337))); vm.prank(address(updaterManager)); home.setUpdater(address(1337)); - assertEq(home.updater(), address(1337)); + assertTrue(home.isNotary(address(1337))); } function test_cannotSetUpdaterManagerAsNotOwner(address _notOwner) public { @@ -71,7 +71,7 @@ contract HomeTest is SynapseTestWithUpdaterManager { } function test_haltsOnFail() public { - home.setFailed(); + home.setFailed(updater); vm.expectRevert("failed state"); home.dispatch( remoteDomain, diff --git a/packages/contracts/test/ReplicaManager.t.sol b/packages/contracts/test/ReplicaManager.t.sol index e792aa31da..ca48cfb3ac 100644 --- a/packages/contracts/test/ReplicaManager.t.sol +++ b/packages/contracts/test/ReplicaManager.t.sol @@ -47,7 +47,7 @@ contract ReplicaManagerTest is SynapseTest { // ============ INITIAL STATE ============ function test_correctlyInitialized() public { assertEq(uint256(replicaManager.localDomain()), uint256(localDomain)); - assertEq(replicaManager.updater(), updater); + assertTrue(replicaManager.isNotary(remoteDomain, updater)); } function test_cannotInitializeTwice() public { @@ -61,14 +61,14 @@ contract ReplicaManagerTest is SynapseTest { vm.assume(_notOwner != replicaManager.owner()); vm.prank(_notOwner); vm.expectRevert("Ownable: caller is not the owner"); - replicaManager.setUpdater(_updater); + replicaManager.setUpdater(remoteDomain, _updater); } function test_setUpdater(address _updater) public { - vm.assume(_updater != replicaManager.updater()); + vm.assume(_updater != updater); vm.prank(replicaManager.owner()); - replicaManager.setUpdater(_updater); - assertEq(replicaManager.updater(), _updater); + replicaManager.setUpdater(remoteDomain, _updater); + assertTrue(replicaManager.isNotary(remoteDomain, _updater)); } function test_cannotSetConfirmationAsNotOwner(address _notOwner) public { @@ -94,7 +94,7 @@ contract ReplicaManagerTest is SynapseTest { assertEq(replicaManager.activeReplicaConfirmedAt(remoteDomain, ROOT), _confirmAt); } - event Update( + event AttestationAccepted( uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, @@ -104,7 +104,7 @@ contract ReplicaManagerTest is SynapseTest { // Relayer relays a new root signed by updater on Home chain function test_successfulUpdate() public { uint32 nonce = 42; - assertEq(replicaManager.updater(), vm.addr(updaterPK)); + assertTrue(replicaManager.isNotary(remoteDomain, vm.addr(updaterPK))); (bytes memory attestation, bytes memory sig) = signRemoteAttestation( updaterPK, nonce, @@ -114,7 +114,7 @@ contract ReplicaManagerTest is SynapseTest { assertEq(replicaManager.activeReplicaConfirmedAt(remoteDomain, ROOT), 0); // Relayer sends over a root signed by the updater on the Home chain vm.expectEmit(true, true, true, true); - emit Update(remoteDomain, nonce, ROOT, sig); + emit AttestationAccepted(remoteDomain, nonce, ROOT, sig); replicaManager.submitAttestation(attestation); // Time at which root was confirmed is set, optimistic timeout starts now assertEq(replicaManager.activeReplicaConfirmedAt(remoteDomain, ROOT), block.timestamp); diff --git a/packages/contracts/test/UpdaterManager.t.sol b/packages/contracts/test/UpdaterManager.t.sol index eb3c249c7e..2d5cabe1fa 100644 --- a/packages/contracts/test/UpdaterManager.t.sol +++ b/packages/contracts/test/UpdaterManager.t.sol @@ -52,12 +52,12 @@ contract UpdaterManagerTest is SynapseTestWithUpdaterManager { function test_setUpdaterAsOwner() public { vm.startPrank(updaterManager.owner()); assertEq(updaterManager.updater(), address(updater)); - assertEq(home.updater(), address(updater)); + assertTrue(home.isNotary(updater)); vm.expectEmit(false, false, false, true); emit NewUpdater(fakeUpdater); updaterManager.setUpdater(address(fakeUpdater)); assertEq(updaterManager.updater(), address(fakeUpdater)); - assertEq(home.updater(), address(fakeUpdater)); + assertTrue(home.isNotary(fakeUpdater)); } function test_cannotSlashUpdaterAsNotHome(address _notHome) public { diff --git a/packages/contracts/test/harnesses/HomeHarness.sol b/packages/contracts/test/harnesses/HomeHarness.sol index c73ac25756..81a085310d 100644 --- a/packages/contracts/test/harnesses/HomeHarness.sol +++ b/packages/contracts/test/harnesses/HomeHarness.sol @@ -9,12 +9,16 @@ contract HomeHarness is Home { constructor(uint32 _domain) Home(_domain) {} + function isNotary(address _notary) public view returns (bool) { + return _isNotary(localDomain, _notary); + } + function setSensitiveValue(uint256 _newValue) external onlySystemMessenger { sensitiveValue = _newValue; } - function setFailed() public { - _fail(); + function setFailed(address _notary) public { + _fail(_notary); } function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) { diff --git a/packages/contracts/test/harnesses/ReplicaManagerHarness.sol b/packages/contracts/test/harnesses/ReplicaManagerHarness.sol index 57366f3e9a..34c8197660 100644 --- a/packages/contracts/test/harnesses/ReplicaManagerHarness.sol +++ b/packages/contracts/test/harnesses/ReplicaManagerHarness.sol @@ -21,6 +21,10 @@ contract ReplicaManagerHarness is ReplicaManager { _addNotary(_domain, _notary); } + function isNotary(uint32 _domain, address _notary) public view returns (bool) { + return _isNotary(_domain, _notary); + } + function setSensitiveValue(uint256 _newValue) external onlySystemMessenger { sensitiveValue = _newValue; } From d3893ee977717ed106040714636e682eeb4e8f1e Mon Sep 17 00:00:00 2001 From: Trajan0x Date: Wed, 10 Aug 2022 19:51:17 +0900 Subject: [PATCH 09/10] regenerate contracts --- .../attestationcollector.abigen.go | 988 +- .../attestationcollector.contractinfo.json | 2 +- core/contracts/home/filterer_generated.go | 72 +- core/contracts/home/home.abigen.go | 6684 ++++++---- core/contracts/home/home.contractinfo.json | 2 +- core/contracts/home/icaller_generated.go | 28 +- core/contracts/home/mocks/i_home.go | 485 +- .../replicamanager/replicamanager.abigen.go | 7775 ++++++----- .../replicamanager.contractinfo.json | 2 +- .../headerharness/headerharness.abigen.go | 10 +- .../headerharness.contractinfo.json | 2 +- .../test/homeharness/homeharness.abigen.go | 9738 ++++++++------ .../homeharness/homeharness.contractinfo.json | 2 +- .../messageharness/messageharness.abigen.go | 12 +- .../messageharness.contractinfo.json | 2 +- .../replicamanagerharness.abigen.go | 10198 +++++++++------ .../replicamanagerharness.contractinfo.json | 2 +- .../test/tipsharness/tipsharness.abigen.go | 12 +- .../tipsharness/tipsharness.contractinfo.json | 2 +- .../updatermanager/updatemanager.abigen.go | 10626 +++++++++------- .../updatemanager.contractinfo.json | 2 +- 21 files changed, 27661 insertions(+), 18985 deletions(-) diff --git a/core/contracts/attestationcollector/attestationcollector.abigen.go b/core/contracts/attestationcollector/attestationcollector.abigen.go index fa16bf3fc9..58888e1910 100644 --- a/core/contracts/attestationcollector/attestationcollector.abigen.go +++ b/core/contracts/attestationcollector/attestationcollector.abigen.go @@ -28,10 +28,161 @@ var ( _ = event.NewSubscription ) +// AbstractNotaryRegistryMetaData contains all meta data concerning the AbstractNotaryRegistry contract. +var AbstractNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractNotaryRegistryMetaData.ABI instead. +var AbstractNotaryRegistryABI = AbstractNotaryRegistryMetaData.ABI + +// AbstractNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractNotaryRegistry struct { + AbstractNotaryRegistryCaller // Read-only binding to the contract + AbstractNotaryRegistryTransactor // Write-only binding to the contract + AbstractNotaryRegistryFilterer // Log filterer for contract events +} + +// AbstractNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractNotaryRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractNotaryRegistrySession struct { + Contract *AbstractNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractNotaryRegistryCallerSession struct { + Contract *AbstractNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractNotaryRegistryTransactorSession struct { + Contract *AbstractNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractNotaryRegistryRaw struct { + Contract *AbstractNotaryRegistry // Generic contract binding to access the raw methods on +} + +// AbstractNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCallerRaw struct { + Contract *AbstractNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactorRaw struct { + Contract *AbstractNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractNotaryRegistry creates a new instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistry(address common.Address, backend bind.ContractBackend) (*AbstractNotaryRegistry, error) { + contract, err := bindAbstractNotaryRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistry{AbstractNotaryRegistryCaller: AbstractNotaryRegistryCaller{contract: contract}, AbstractNotaryRegistryTransactor: AbstractNotaryRegistryTransactor{contract: contract}, AbstractNotaryRegistryFilterer: AbstractNotaryRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractNotaryRegistryCaller creates a new read-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractNotaryRegistryCaller, error) { + contract, err := bindAbstractNotaryRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryCaller{contract: contract}, nil +} + +// NewAbstractNotaryRegistryTransactor creates a new write-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractNotaryRegistryTransactor, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryTransactor{contract: contract}, nil +} + +// NewAbstractNotaryRegistryFilterer creates a new log filterer instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractNotaryRegistryFilterer, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryFilterer{contract: contract}, nil +} + +// bindAbstractNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractNotaryRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transact(opts, method, params...) +} + // AddressUpgradeableMetaData contains all meta data concerning the AddressUpgradeable contract. var AddressUpgradeableMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205130aff3af56b954e70d84f1f71053f5fc7fc4bbbdc98965c9cb5de6af4f96ec64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220805edcea6ad8f670347550cddf18353b53fb4e3924b563093c0d20a8ecd780f564736f6c634300080d0033", } // AddressUpgradeableABI is the input ABI used to generate the binding from. @@ -204,7 +355,7 @@ func (_AddressUpgradeable *AddressUpgradeableTransactorRaw) Transact(opts *bind. // AttestationMetaData contains all meta data concerning the Attestation contract. var AttestationMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206e0abd69af18e5e395d1508ee8761beefbf7b753a40677f7fc409c34d1640e6664736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205fdc42d61385a9fedec2650f0f5625d6cd35f51e97fa6fd2ec166a54aacff00564736f6c634300080d0033", } // AttestationABI is the input ABI used to generate the binding from. @@ -394,7 +545,7 @@ var AttestationCollectorMetaData = &bind.MetaData{ "f646a512": "submitAttestation(bytes)", "f2fde38b": "transferOwnership(address)", }, - Bin: "0x608060405234801561001057600080fd5b506127e1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638129fc1c11610097578063d451680311610066578063d4516803146101ec578063d53f2eec14610217578063f2fde38b1461025d578063f646a5121461027057600080fd5b80638129fc1c146101965780638da5cb5b1461019e578063a7d729bd146101c6578063bb07a791146101d957600080fd5b80634b82bad7116100d35780634b82bad714610148578063563ffbec1461015b578063715018a61461017b5780637eb2923f1461018357600080fd5b806317007970146100fa578063289def8d146101205780632af678b014610133575b600080fd5b61010d61010836600461223d565b610293565b6040519081526020015b60405180910390f35b61010d61012e366004612270565b6102bd565b6101466101413660046122d0565b61037e565b005b6101466101563660046122d0565b6103f4565b61016e610169366004612270565b610465565b6040516101179190612374565b6101466104d1565b61016e6101913660046122d0565b610544565b61014661061b565b60975460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b61016e6101d4366004612387565b6106ca565b61016e6101e7366004612270565b610865565b61010d6101fa3660046122d0565b60cc60209081526000928352604080842090915290825290205481565b6102486102253660046122d0565b60cb60209081526000928352604080842090915290825290205463ffffffff1681565b60405163ffffffff9091168152602001610117565b61014661026b3660046123a2565b610881565b61028361027e3660046123ec565b61097a565b6040519015158152602001610117565b63ffffffff808316600090815260c960209081526040808320938516835292905220545b92915050565b63ffffffff808416600090815260c96020908152604080832093861683529290529081205482106103355760405162461bcd60e51b815260206004820152600660248201527f21696e646578000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b63ffffffff808516600090815260c960209081526040808320938716835292905220805483908110610369576103696124bb565b906000526020600020015490505b9392505050565b60975473ffffffffffffffffffffffffffffffffffffffff1633146103e55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef82826109f4565b505050565b60975473ffffffffffffffffffffffffffffffffffffffff16331461045b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef8282610af1565b6060610472848484610d1a565b6104be5760405162461bcd60e51b815260206004820152600a60248201527f217369676e617475726500000000000000000000000000000000000000000000604482015260640161032c565b6104c9848484610d60565b949350505050565b60975473ffffffffffffffffffffffffffffffffffffffff1633146105385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6105426000610e73565b565b63ffffffff808316600090815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205460609216908190036105d05760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b63ffffffff8416600090815260cc6020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610612858383610d60565b95945050505050565b60006106276001610eea565b9050801561065c57606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610664611043565b80156106c757606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b63ffffffff81166000908152603260205260408120546060918190036107325760405162461bcd60e51b815260206004820152600960248201527f216e6f7461726965730000000000000000000000000000000000000000000000604482015260640161032c565b600080805b838110156108035763ffffffff86166000908152603260205260408120805483908110610766576107666124bb565b600091825260208083209091015463ffffffff808b16845260cb8352604080852073ffffffffffffffffffffffffffffffffffffffff9093168086529290935291909220549192509081169085168111156107f95763ffffffff8816600090815260cc6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020549094509250835b5050600101610737565b508163ffffffff1660000361085a5760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b610612858383610d60565b606060006108748585856102bd565b9050610612858583610d60565b60975473ffffffffffffffffffffffffffffffffffffffff1633146108e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b73ffffffffffffffffffffffffffffffffffffffff81166109715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161032c565b6106c781610e73565b6000806000610988846110c9565b9150915061099682826111d9565b925082156109ed578173ffffffffffffffffffffffffffffffffffffffff167f786431104fc3c4b19da7bae78f422f46b9c07528276a2ee430e8569cb8705f14856040516109e49190612374565b60405180910390a25b5050919050565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415610a38575060006102b7565b63ffffffff8316600081815260326020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546033845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054808203610b395760009150506102b7565b63ffffffff8416600090815260326020526040812090610b5a600184612519565b8254909150600090610b6e90600190612519565b9050818114610c3a576000838281548110610b8b57610b8b6124bb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080848481548110610bcb57610bcb6124bb565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94851617905563ffffffff8b1682526033815260408083209490931682529290925290208490555b82805480610c4a57610c4a612530565b600082815260208082207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908401810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925563ffffffff891680835260338252604080842073ffffffffffffffffffffffffffffffffffffffff8b168086529084528185209490945551928352917f3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b910160405180910390a25060019695505050505050565b63ffffffff808416600090815260ca60209081526040808320938616835292815282822084835290529081208054829190610d549061255f565b90501190509392505050565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086811b8216602084015285901b16602482015260288082018490528251808303909101815260489091019091526060906104c99063ffffffff808716600090815260ca6020908152604080832093891683529281528282208783529052208054610df09061255f565b80601f0160208091040260200160405190810160405280929190818152602001828054610e1c9061255f565b8015610e695780601f10610e3e57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610e4c57829003601f168201915b50505050506113c9565b6097805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606454600090610100900460ff1615610f89578160ff166001148015610f0f5750303b155b610f815760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b506000919050565b60645460ff8084169116106110065760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b50606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b606454610100900460ff166110c05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161032c565b61054233610e73565b6000806110d683826113f5565b905060286bffffffffffffffffffffffff601883901c161161113a5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161032c565b61116e61114c62ffffff198316611410565b61116961115e62ffffff198516611425565b62ffffff1916611458565b6114ab565b915061118861118262ffffff198316611522565b83611536565b6111d45760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161032c565b915091565b6000806111eb62ffffff198416611522565b905060006111fe62ffffff198516611574565b9050600061121162ffffff198616611588565b63ffffffff808516600090815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1684529091529020549192509081169083161161129f5760405162461bcd60e51b815260206004820152601460248201527f4f75746461746564206174746573746174696f6e000000000000000000000000604482015260640161032c565b6112aa838383610d1a565b156112bb57600093505050506102b7565b63ffffffff838116600081815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000169689169690961790955592825260cc815282822093825292909252902081905561134a61115e62ffffff198716611425565b63ffffffff808516600090815260ca602090815260408083209387168352928152828220858352815291902082516113889391929190910190612190565b5063ffffffff928316600090815260c96020908152604080832094909516825292835292832080546001808201835591855292909320909101559392505050565b606082826040516020016113de9291906125ac565b604051602081830303815290604052905092915050565b81516000906020840161061264ffffffffff8516828461159d565b60006102b762ffffff198316826028816115e2565b60006102b7602861144881601886901c6bffffffffffffffffffffffff16612519565b62ffffff198516919060006115e2565b60606000806114758460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050604051915081925061149a8483602001611666565b508181016020016040529052919050565b6000806114bd62ffffff198516611801565b9050611516816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506104c9818461185e565b60006102b762ffffff198316826004611882565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091528120541515610377565b60006102b762ffffff198316600480611882565b60006102b762ffffff198316600860206118b2565b6000806115aa83856125db565b90506040518111156115ba575060005b806000036115cf5762ffffff19915050610377565b606085811b8517901b831760181b610612565b6000806115fd8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061161686611a70565b8461162187846125db565b61162b91906125db565b111561163e5762ffffff199150506104c9565b61164885826125db565b905061165c8364ffffffffff16828661159d565b9695505050505050565b600062ffffff19808416036116e35760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161032c565b6116ec83611ab8565b61175e5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161032c565b60006117788460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006117a28560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156117c75760206060fd5b8285848460045afa5061165c6117dd8760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b60008061181c8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006118468460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061186d8585611af5565b9150915061187a81611b63565b509392505050565b600061188f8260206125f3565b61189a906008612616565b60ff166118a88585856118b2565b901c949350505050565b60008160ff166000036118c757506000610377565b6118df8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118fa60ff8416856125db565b11156119725761195961191b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119418660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16611d4f565b60405162461bcd60e51b815260040161032c9190612374565b60208260ff1611156119ec5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161032c565b600882026000611a0a8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000611a8a8260181c6bffffffffffffffffffffffff1690565b611aa28360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000611ac48260d81c90565b64ffffffffff1664ffffffffff03611ade57506000919050565b6000611ae983611a70565b60405110199392505050565b6000808251604103611b2b5760208301516040840151606085015160001a611b1f87828585611dbd565b94509450505050611b5c565b8251604003611b545760208301516040840151611b49868383611ed5565b935093505050611b5c565b506000905060025b9250929050565b6000816004811115611b7757611b7761263f565b03611b7f5750565b6001816004811115611b9357611b9361263f565b03611be05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161032c565b6002816004811115611bf457611bf461263f565b03611c415760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161032c565b6003816004811115611c5557611c5561263f565b03611cc85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b6004816004811115611cdc57611cdc61263f565b036106c75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b60606000611d5c86611f27565b9150506000611d6a86611f27565b9150506000611d7886611f27565b9150506000611d8686611f27565b91505083838383604051602001611da0949392919061266e565b604051602081830303815290604052945050505050949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611df45750600090506003611ecc565b8460ff16601b14158015611e0c57508460ff16601c14155b15611e1d5750600090506004611ecc565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e71573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611ec557600060019250925050611ecc565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681611f0b60ff86901c601b6125db565b9050611f1987828885611dbd565b935093505050935093915050565b600080601f5b600f8160ff161115611f9a576000611f46826008612616565b60ff1685901c9050611f5781612011565b61ffff16841793508160ff16601014611f7257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f2d565b50600f5b60ff8160ff16101561200b576000611fb7826008612616565b60ff1685901c9050611fc881612011565b61ffff16831792508160ff16600014611fe357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f9e565b50915091565b600061202360048360ff16901c612043565b60ff1661ffff919091161760081b61203a82612043565b60ff1617919050565b600060f08083179060ff8216900361205e5750603092915050565b8060ff1660f1036120725750603192915050565b8060ff1660f2036120865750603292915050565b8060ff1660f30361209a5750603392915050565b8060ff1660f4036120ae5750603492915050565b8060ff1660f5036120c25750603592915050565b8060ff1660f6036120d65750603692915050565b8060ff1660f7036120ea5750603792915050565b8060ff1660f8036120fe5750603892915050565b8060ff1660f9036121125750603992915050565b8060ff1660fa036121265750606192915050565b8060ff1660fb0361213a5750606292915050565b8060ff1660fc0361214e5750606392915050565b8060ff1660fd036121625750606492915050565b8060ff1660fe036121765750606592915050565b8060ff1660ff0361218a5750606692915050565b50919050565b82805461219c9061255f565b90600052602060002090601f0160209004810192826121be5760008555612204565b82601f106121d757805160ff1916838001178555612204565b82800160010185558215612204579182015b828111156122045782518255916020019190600101906121e9565b50612210929150612214565b5090565b5b808211156122105760008155600101612215565b803563ffffffff8116811461103e57600080fd5b6000806040838503121561225057600080fd5b61225983612229565b915061226760208401612229565b90509250929050565b60008060006060848603121561228557600080fd5b61228e84612229565b925061229c60208501612229565b9150604084013590509250925092565b803573ffffffffffffffffffffffffffffffffffffffff8116811461103e57600080fd5b600080604083850312156122e357600080fd5b6122ec83612229565b9150612267602084016122ac565b60005b838110156123155781810151838201526020016122fd565b83811115612324576000848401525b50505050565b600081518084526123428160208601602086016122fa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610377602083018461232a565b60006020828403121561239957600080fd5b61037782612229565b6000602082840312156123b457600080fd5b610377826122ac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156123fe57600080fd5b813567ffffffffffffffff8082111561241657600080fd5b818401915084601f83011261242a57600080fd5b81358181111561243c5761243c6123bd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612482576124826123bd565b8160405282815287602084870101111561249b57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561252b5761252b6124ea565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600181811c9082168061257357607f821691505b60208210810361218a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600083516125be8184602088016122fa565b8351908301906125d28183602088016122fa565b01949350505050565b600082198211156125ee576125ee6124ea565b500190565b600060ff821660ff84168082101561260d5761260d6124ea565b90039392505050565b600060ff821660ff84168160ff0481118215151615612637576126376124ea565b029392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161165c56fea2646970667358221220d5c9d5ae9e7ee85d4eaa5a58fd7d248f12b96317130c56c1dfa25865fd224ff864736f6c634300080d0033", + Bin: "0x608060405234801561001057600080fd5b506127d8806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638129fc1c11610097578063d451680311610066578063d4516803146101ec578063d53f2eec14610217578063f2fde38b1461025d578063f646a5121461027057600080fd5b80638129fc1c146101965780638da5cb5b1461019e578063a7d729bd146101c6578063bb07a791146101d957600080fd5b80634b82bad7116100d35780634b82bad714610148578063563ffbec1461015b578063715018a61461017b5780637eb2923f1461018357600080fd5b806317007970146100fa578063289def8d146101205780632af678b014610133575b600080fd5b61010d610108366004612234565b610293565b6040519081526020015b60405180910390f35b61010d61012e366004612267565b6102bd565b6101466101413660046122c7565b61037e565b005b6101466101563660046122c7565b6103f4565b61016e610169366004612267565b610465565b604051610117919061236b565b6101466104d1565b61016e6101913660046122c7565b610544565b61014661061b565b60655460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b61016e6101d436600461237e565b6106ca565b61016e6101e7366004612267565b610865565b61010d6101fa3660046122c7565b609a60209081526000928352604080842090915290825290205481565b6102486102253660046122c7565b609960209081526000928352604080842090915290825290205463ffffffff1681565b60405163ffffffff9091168152602001610117565b61014661026b366004612399565b610881565b61028361027e3660046123e3565b61097a565b6040519015158152602001610117565b63ffffffff8083166000908152609760209081526040808320938516835292905220545b92915050565b63ffffffff808416600090815260976020908152604080832093861683529290529081205482106103355760405162461bcd60e51b815260206004820152600660248201527f21696e646578000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b63ffffffff8085166000908152609760209081526040808320938716835292905220805483908110610369576103696124b2565b906000526020600020015490505b9392505050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146103e55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef82826109f4565b505050565b60655473ffffffffffffffffffffffffffffffffffffffff16331461045b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef8282610af1565b6060610472848484610d1a565b6104be5760405162461bcd60e51b815260206004820152600a60248201527f217369676e617475726500000000000000000000000000000000000000000000604482015260640161032c565b6104c9848484610d60565b949350505050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146105385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6105426000610e73565b565b63ffffffff808316600090815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205460609216908190036105d05760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b63ffffffff84166000908152609a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610612858383610d60565b95945050505050565b60006106276001610eea565b9050801561065c57603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610664611043565b80156106c757603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b63ffffffff81166000908152602081905260408120546060918190036107325760405162461bcd60e51b815260206004820152600960248201527f216e6f7461726965730000000000000000000000000000000000000000000000604482015260640161032c565b600080805b838110156108035763ffffffff86166000908152602081905260408120805483908110610766576107666124b2565b600091825260208083209091015463ffffffff808b16845260998352604080852073ffffffffffffffffffffffffffffffffffffffff9093168086529290935291909220549192509081169085168111156107f95763ffffffff88166000908152609a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020549094509250835b5050600101610737565b508163ffffffff1660000361085a5760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b610612858383610d60565b606060006108748585856102bd565b9050610612858583610d60565b60655473ffffffffffffffffffffffffffffffffffffffff1633146108e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b73ffffffffffffffffffffffffffffffffffffffff81166109715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161032c565b6106c781610e73565b6000806000610988846110c9565b91509150610996828261120e565b925082156109ed578173ffffffffffffffffffffffffffffffffffffffff167f786431104fc3c4b19da7bae78f422f46b9c07528276a2ee430e8569cb8705f14856040516109e4919061236b565b60405180910390a25b5050919050565b63ffffffff8216600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415610a38575060006102b7565b63ffffffff831660008181526020818152604080832080546001808201835582865284862090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16908117909155868652915490845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b63ffffffff8216600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054808203610b395760009150506102b7565b63ffffffff8416600090815260208190526040812090610b5a600184612510565b8254909150600090610b6e90600190612510565b9050818114610c3a576000838281548110610b8b57610b8b6124b2565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080848481548110610bcb57610bcb6124b2565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94851617905563ffffffff8b1682526001815260408083209490931682529290925290208490555b82805480610c4a57610c4a612527565b600082815260208082207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908401810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925563ffffffff891680835260018252604080842073ffffffffffffffffffffffffffffffffffffffff8b168086529084528185209490945551928352917f3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b910160405180910390a25060019695505050505050565b63ffffffff8084166000908152609860209081526040808320938616835292815282822084835290529081208054829190610d5490612556565b90501190509392505050565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086811b8216602084015285901b16602482015260288082018490528251808303909101815260489091019091526060906104c99063ffffffff808716600090815260986020908152604080832093891683529281528282208783529052208054610df090612556565b80601f0160208091040260200160405190810160405280929190818152602001828054610e1c90612556565b8015610e695780601f10610e3e57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610e4c57829003601f168201915b50505050506113fe565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b603254600090610100900460ff1615610f89578160ff166001148015610f0f5750303b155b610f815760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b506000919050565b60325460ff8084169116106110065760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b50603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b603254610100900460ff166110c05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161032c565b61054233610e73565b6000806110d6838261142a565b905060286bffffffffffffffffffffffff601883901c161161113a5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161032c565b61116e61114c62ffffff198316611445565b61116961115e62ffffff19851661145a565b62ffffff191661148d565b6114e0565b91506111bd61118262ffffff198316611557565b63ffffffff16600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6112095760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161032c565b915091565b60008061122062ffffff198416611557565b9050600061123362ffffff19851661156b565b9050600061124662ffffff19861661157f565b63ffffffff808516600090815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c168452909152902054919250908116908316116112d45760405162461bcd60e51b815260206004820152601460248201527f4f75746461746564206174746573746174696f6e000000000000000000000000604482015260640161032c565b6112df838383610d1a565b156112f057600093505050506102b7565b63ffffffff838116600081815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001696891696909617909555928252609a815282822093825292909252902081905561137f61115e62ffffff19871661145a565b63ffffffff80851660009081526098602090815260408083209387168352928152828220858352815291902082516113bd9391929190910190612187565b5063ffffffff928316600090815260976020908152604080832094909516825292835292832080546001808201835591855292909320909101559392505050565b606082826040516020016114139291906125a3565b604051602081830303815290604052905092915050565b81516000906020840161061264ffffffffff85168284611594565b60006102b762ffffff198316826028816115d9565b60006102b7602861147d81601886901c6bffffffffffffffffffffffff16612510565b62ffffff198516919060006115d9565b60606000806114aa8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506114cf848360200161165d565b508181016020016040529052919050565b6000806114f262ffffff1985166117f8565b905061154b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506104c98184611855565b60006102b762ffffff198316826004611879565b60006102b762ffffff198316600480611879565b60006102b762ffffff198316600860206118a9565b6000806115a183856125d2565b90506040518111156115b1575060005b806000036115c65762ffffff19915050610377565b606085811b8517901b831760181b610612565b6000806115f48660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061160d86611a67565b8461161887846125d2565b61162291906125d2565b11156116355762ffffff199150506104c9565b61163f85826125d2565b90506116538364ffffffffff168286611594565b9695505050505050565b600062ffffff19808416036116da5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161032c565b6116e383611aaf565b6117555760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161032c565b600061176f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006117998560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156117be5760206060fd5b8285848460045afa506116536117d48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806118138360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061183d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006118648585611aec565b9150915061187181611b5a565b509392505050565b60006118868260206125ea565b61189190600861260d565b60ff1661189f8585856118a9565b901c949350505050565b60008160ff166000036118be57506000610377565b6118d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118f160ff8416856125d2565b1115611969576119506119128560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119388660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16611d46565b60405162461bcd60e51b815260040161032c919061236b565b60208260ff1611156119e35760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161032c565b600882026000611a018660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000611a818260181c6bffffffffffffffffffffffff1690565b611a998360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000611abb8260d81c90565b64ffffffffff1664ffffffffff03611ad557506000919050565b6000611ae083611a67565b60405110199392505050565b6000808251604103611b225760208301516040840151606085015160001a611b1687828585611db4565b94509450505050611b53565b8251604003611b4b5760208301516040840151611b40868383611ecc565b935093505050611b53565b506000905060025b9250929050565b6000816004811115611b6e57611b6e612636565b03611b765750565b6001816004811115611b8a57611b8a612636565b03611bd75760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161032c565b6002816004811115611beb57611beb612636565b03611c385760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161032c565b6003816004811115611c4c57611c4c612636565b03611cbf5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b6004816004811115611cd357611cd3612636565b036106c75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b60606000611d5386611f1e565b9150506000611d6186611f1e565b9150506000611d6f86611f1e565b9150506000611d7d86611f1e565b91505083838383604051602001611d979493929190612665565b604051602081830303815290604052945050505050949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611deb5750600090506003611ec3565b8460ff16601b14158015611e0357508460ff16601c14155b15611e145750600090506004611ec3565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e68573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611ebc57600060019250925050611ec3565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681611f0260ff86901c601b6125d2565b9050611f1087828885611db4565b935093505050935093915050565b600080601f5b600f8160ff161115611f91576000611f3d82600861260d565b60ff1685901c9050611f4e81612008565b61ffff16841793508160ff16601014611f6957601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f24565b50600f5b60ff8160ff161015612002576000611fae82600861260d565b60ff1685901c9050611fbf81612008565b61ffff16831792508160ff16600014611fda57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f95565b50915091565b600061201a60048360ff16901c61203a565b60ff1661ffff919091161760081b6120318261203a565b60ff1617919050565b600060f08083179060ff821690036120555750603092915050565b8060ff1660f1036120695750603192915050565b8060ff1660f20361207d5750603292915050565b8060ff1660f3036120915750603392915050565b8060ff1660f4036120a55750603492915050565b8060ff1660f5036120b95750603592915050565b8060ff1660f6036120cd5750603692915050565b8060ff1660f7036120e15750603792915050565b8060ff1660f8036120f55750603892915050565b8060ff1660f9036121095750603992915050565b8060ff1660fa0361211d5750606192915050565b8060ff1660fb036121315750606292915050565b8060ff1660fc036121455750606392915050565b8060ff1660fd036121595750606492915050565b8060ff1660fe0361216d5750606592915050565b8060ff1660ff036121815750606692915050565b50919050565b82805461219390612556565b90600052602060002090601f0160209004810192826121b557600085556121fb565b82601f106121ce57805160ff19168380011785556121fb565b828001600101855582156121fb579182015b828111156121fb5782518255916020019190600101906121e0565b5061220792915061220b565b5090565b5b80821115612207576000815560010161220c565b803563ffffffff8116811461103e57600080fd5b6000806040838503121561224757600080fd5b61225083612220565b915061225e60208401612220565b90509250929050565b60008060006060848603121561227c57600080fd5b61228584612220565b925061229360208501612220565b9150604084013590509250925092565b803573ffffffffffffffffffffffffffffffffffffffff8116811461103e57600080fd5b600080604083850312156122da57600080fd5b6122e383612220565b915061225e602084016122a3565b60005b8381101561230c5781810151838201526020016122f4565b8381111561231b576000848401525b50505050565b600081518084526123398160208601602086016122f1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006103776020830184612321565b60006020828403121561239057600080fd5b61037782612220565b6000602082840312156123ab57600080fd5b610377826122a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156123f557600080fd5b813567ffffffffffffffff8082111561240d57600080fd5b818401915084601f83011261242157600080fd5b813581811115612433576124336123b4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612479576124796123b4565b8160405282815287602084870101111561249257600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612522576125226124e1565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600181811c9082168061256a57607f821691505b602082108103612181577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600083516125b58184602088016122f1565b8351908301906125c98183602088016122f1565b01949350505050565b600082198211156125e5576125e56124e1565b500190565b600060ff821660ff841680821015612604576126046124e1565b90039392505050565b600060ff821660ff84168160ff048111821515161561262e5761262e6124e1565b029392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161165356fea2646970667358221220282727d67bb627ed57f2f72ef2060c7fa79561d82a651fdd63c80edd00ecd8fe64736f6c634300080d0033", } // AttestationCollectorABI is the input ABI used to generate the binding from. @@ -1698,7 +1849,7 @@ func (_AttestationCollector *AttestationCollectorFilterer) ParseOwnershipTransfe // AuthMetaData contains all meta data concerning the Auth contract. var AuthMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201424546045ea27bec3e25d3f0ff3c80b4568503c646b3ee3fa51a36a155ce67f64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d5b7a52c73012a882764841613e5f3362e0d556e49785a931383b0d71dc4010964736f6c634300080d0033", } // AuthABI is the input ABI used to generate the binding from. @@ -1868,157 +2019,6 @@ func (_Auth *AuthTransactorRaw) Transact(opts *bind.TransactOpts, method string, return _Auth.Contract.contract.Transact(opts, method, params...) } -// AuthManagerMetaData contains all meta data concerning the AuthManager contract. -var AuthManagerMetaData = &bind.MetaData{ - ABI: "[]", -} - -// AuthManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use AuthManagerMetaData.ABI instead. -var AuthManagerABI = AuthManagerMetaData.ABI - -// AuthManager is an auto generated Go binding around an Ethereum contract. -type AuthManager struct { - AuthManagerCaller // Read-only binding to the contract - AuthManagerTransactor // Write-only binding to the contract - AuthManagerFilterer // Log filterer for contract events -} - -// AuthManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type AuthManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type AuthManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type AuthManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type AuthManagerSession struct { - Contract *AuthManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type AuthManagerCallerSession struct { - Contract *AuthManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// AuthManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type AuthManagerTransactorSession struct { - Contract *AuthManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type AuthManagerRaw struct { - Contract *AuthManager // Generic contract binding to access the raw methods on -} - -// AuthManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type AuthManagerCallerRaw struct { - Contract *AuthManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// AuthManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type AuthManagerTransactorRaw struct { - Contract *AuthManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewAuthManager creates a new instance of AuthManager, bound to a specific deployed contract. -func NewAuthManager(address common.Address, backend bind.ContractBackend) (*AuthManager, error) { - contract, err := bindAuthManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &AuthManager{AuthManagerCaller: AuthManagerCaller{contract: contract}, AuthManagerTransactor: AuthManagerTransactor{contract: contract}, AuthManagerFilterer: AuthManagerFilterer{contract: contract}}, nil -} - -// NewAuthManagerCaller creates a new read-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerCaller(address common.Address, caller bind.ContractCaller) (*AuthManagerCaller, error) { - contract, err := bindAuthManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &AuthManagerCaller{contract: contract}, nil -} - -// NewAuthManagerTransactor creates a new write-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*AuthManagerTransactor, error) { - contract, err := bindAuthManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &AuthManagerTransactor{contract: contract}, nil -} - -// NewAuthManagerFilterer creates a new log filterer instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*AuthManagerFilterer, error) { - contract, err := bindAuthManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &AuthManagerFilterer{contract: contract}, nil -} - -// bindAuthManager binds a generic wrapper to an already deployed contract. -func bindAuthManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(AuthManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.AuthManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transact(opts, method, params...) -} - // ContextUpgradeableMetaData contains all meta data concerning the ContextUpgradeable contract. var ContextUpgradeableMetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", @@ -2307,7 +2307,7 @@ func (_ContextUpgradeable *ContextUpgradeableFilterer) ParseInitialized(log type // ECDSAMetaData contains all meta data concerning the ECDSA contract. var ECDSAMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e9653e8e5505d59889cb00d1307a68b4424be601af807311fbda8f71a299512764736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220130420b187d25337d68f61342ab408fbb130895eb57445a73b06d7919fafae9b64736f6c634300080d0033", } // ECDSAABI is the input ABI used to generate the binding from. @@ -2477,113 +2477,135 @@ func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method strin return _ECDSA.Contract.contract.Transact(opts, method, params...) } -// InitializableMetaData contains all meta data concerning the Initializable contract. -var InitializableMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", +// GlobalNotaryRegistryMetaData contains all meta data concerning the GlobalNotaryRegistry contract. +var GlobalNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"}]", + Bin: "0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea264697066735822122046c73ffb3fd7d4a2d5c3476a63813ec913af2cb8914e234c584c98c484a7e70e64736f6c634300080d0033", } -// InitializableABI is the input ABI used to generate the binding from. -// Deprecated: Use InitializableMetaData.ABI instead. -var InitializableABI = InitializableMetaData.ABI +// GlobalNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use GlobalNotaryRegistryMetaData.ABI instead. +var GlobalNotaryRegistryABI = GlobalNotaryRegistryMetaData.ABI -// Initializable is an auto generated Go binding around an Ethereum contract. -type Initializable struct { - InitializableCaller // Read-only binding to the contract - InitializableTransactor // Write-only binding to the contract - InitializableFilterer // Log filterer for contract events +// GlobalNotaryRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GlobalNotaryRegistryMetaData.Bin instead. +var GlobalNotaryRegistryBin = GlobalNotaryRegistryMetaData.Bin + +// DeployGlobalNotaryRegistry deploys a new Ethereum contract, binding an instance of GlobalNotaryRegistry to it. +func DeployGlobalNotaryRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GlobalNotaryRegistry, error) { + parsed, err := GlobalNotaryRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GlobalNotaryRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GlobalNotaryRegistry{GlobalNotaryRegistryCaller: GlobalNotaryRegistryCaller{contract: contract}, GlobalNotaryRegistryTransactor: GlobalNotaryRegistryTransactor{contract: contract}, GlobalNotaryRegistryFilterer: GlobalNotaryRegistryFilterer{contract: contract}}, nil } -// InitializableCaller is an auto generated read-only Go binding around an Ethereum contract. -type InitializableCaller struct { +// GlobalNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type GlobalNotaryRegistry struct { + GlobalNotaryRegistryCaller // Read-only binding to the contract + GlobalNotaryRegistryTransactor // Write-only binding to the contract + GlobalNotaryRegistryFilterer // Log filterer for contract events +} + +// GlobalNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// InitializableTransactor is an auto generated write-only Go binding around an Ethereum contract. -type InitializableTransactor struct { +// GlobalNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// InitializableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type InitializableFilterer struct { +// GlobalNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GlobalNotaryRegistryFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// InitializableSession is an auto generated Go binding around an Ethereum contract, +// GlobalNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type InitializableSession struct { - Contract *Initializable // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type GlobalNotaryRegistrySession struct { + Contract *GlobalNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// InitializableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// GlobalNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type InitializableCallerSession struct { - Contract *InitializableCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type GlobalNotaryRegistryCallerSession struct { + Contract *GlobalNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// InitializableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// GlobalNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type InitializableTransactorSession struct { - Contract *InitializableTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type GlobalNotaryRegistryTransactorSession struct { + Contract *GlobalNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// InitializableRaw is an auto generated low-level Go binding around an Ethereum contract. -type InitializableRaw struct { - Contract *Initializable // Generic contract binding to access the raw methods on +// GlobalNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type GlobalNotaryRegistryRaw struct { + Contract *GlobalNotaryRegistry // Generic contract binding to access the raw methods on } -// InitializableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type InitializableCallerRaw struct { - Contract *InitializableCaller // Generic read-only contract binding to access the raw methods on +// GlobalNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryCallerRaw struct { + Contract *GlobalNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on } -// InitializableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type InitializableTransactorRaw struct { - Contract *InitializableTransactor // Generic write-only contract binding to access the raw methods on +// GlobalNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryTransactorRaw struct { + Contract *GlobalNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on } -// NewInitializable creates a new instance of Initializable, bound to a specific deployed contract. -func NewInitializable(address common.Address, backend bind.ContractBackend) (*Initializable, error) { - contract, err := bindInitializable(address, backend, backend, backend) +// NewGlobalNotaryRegistry creates a new instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistry(address common.Address, backend bind.ContractBackend) (*GlobalNotaryRegistry, error) { + contract, err := bindGlobalNotaryRegistry(address, backend, backend, backend) if err != nil { return nil, err } - return &Initializable{InitializableCaller: InitializableCaller{contract: contract}, InitializableTransactor: InitializableTransactor{contract: contract}, InitializableFilterer: InitializableFilterer{contract: contract}}, nil + return &GlobalNotaryRegistry{GlobalNotaryRegistryCaller: GlobalNotaryRegistryCaller{contract: contract}, GlobalNotaryRegistryTransactor: GlobalNotaryRegistryTransactor{contract: contract}, GlobalNotaryRegistryFilterer: GlobalNotaryRegistryFilterer{contract: contract}}, nil } -// NewInitializableCaller creates a new read-only instance of Initializable, bound to a specific deployed contract. -func NewInitializableCaller(address common.Address, caller bind.ContractCaller) (*InitializableCaller, error) { - contract, err := bindInitializable(address, caller, nil, nil) +// NewGlobalNotaryRegistryCaller creates a new read-only instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*GlobalNotaryRegistryCaller, error) { + contract, err := bindGlobalNotaryRegistry(address, caller, nil, nil) if err != nil { return nil, err } - return &InitializableCaller{contract: contract}, nil + return &GlobalNotaryRegistryCaller{contract: contract}, nil } -// NewInitializableTransactor creates a new write-only instance of Initializable, bound to a specific deployed contract. -func NewInitializableTransactor(address common.Address, transactor bind.ContractTransactor) (*InitializableTransactor, error) { - contract, err := bindInitializable(address, nil, transactor, nil) +// NewGlobalNotaryRegistryTransactor creates a new write-only instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*GlobalNotaryRegistryTransactor, error) { + contract, err := bindGlobalNotaryRegistry(address, nil, transactor, nil) if err != nil { return nil, err } - return &InitializableTransactor{contract: contract}, nil + return &GlobalNotaryRegistryTransactor{contract: contract}, nil } -// NewInitializableFilterer creates a new log filterer instance of Initializable, bound to a specific deployed contract. -func NewInitializableFilterer(address common.Address, filterer bind.ContractFilterer) (*InitializableFilterer, error) { - contract, err := bindInitializable(address, nil, nil, filterer) +// NewGlobalNotaryRegistryFilterer creates a new log filterer instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*GlobalNotaryRegistryFilterer, error) { + contract, err := bindGlobalNotaryRegistry(address, nil, nil, filterer) if err != nil { return nil, err } - return &InitializableFilterer{contract: contract}, nil + return &GlobalNotaryRegistryFilterer{contract: contract}, nil } -// bindInitializable binds a generic wrapper to an already deployed contract. -func bindInitializable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(InitializableABI)) +// bindGlobalNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindGlobalNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(GlobalNotaryRegistryABI)) if err != nil { return nil, err } @@ -2594,43 +2616,43 @@ func bindInitializable(address common.Address, caller bind.ContractCaller, trans // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Initializable *InitializableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Initializable.Contract.InitializableCaller.contract.Call(opts, result, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Initializable *InitializableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Initializable.Contract.InitializableTransactor.contract.Transfer(opts) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Initializable *InitializableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Initializable.Contract.InitializableTransactor.contract.Transact(opts, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Initializable *InitializableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Initializable.Contract.contract.Call(opts, result, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GlobalNotaryRegistry.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Initializable *InitializableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Initializable.Contract.contract.Transfer(opts) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Initializable *InitializableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Initializable.Contract.contract.Transact(opts, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.contract.Transact(opts, method, params...) } -// InitializableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Initializable contract. -type InitializableInitializedIterator struct { - Event *InitializableInitialized // Event containing the contract specifics and raw log +// GlobalNotaryRegistryNotaryAddedIterator is returned from FilterNotaryAdded and is used to iterate over the raw logs and unpacked data for NotaryAdded events raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryAddedIterator struct { + Event *GlobalNotaryRegistryNotaryAdded // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2644,7 +2666,7 @@ type InitializableInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *InitializableInitializedIterator) Next() bool { +func (it *GlobalNotaryRegistryNotaryAddedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2653,7 +2675,7 @@ func (it *InitializableInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(InitializableInitialized) + it.Event = new(GlobalNotaryRegistryNotaryAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2668,7 +2690,7 @@ func (it *InitializableInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(InitializableInitialized) + it.Event = new(GlobalNotaryRegistryNotaryAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2684,41 +2706,52 @@ func (it *InitializableInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *InitializableInitializedIterator) Error() error { +func (it *GlobalNotaryRegistryNotaryAddedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *InitializableInitializedIterator) Close() error { +func (it *GlobalNotaryRegistryNotaryAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -// InitializableInitialized represents a Initialized event raised by the Initializable contract. -type InitializableInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// GlobalNotaryRegistryNotaryAdded represents a NotaryAdded event raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryAdded struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterNotaryAdded is a free log retrieval operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) FilterInitialized(opts *bind.FilterOpts) (*InitializableInitializedIterator, error) { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) FilterNotaryAdded(opts *bind.FilterOpts, domain []uint32) (*GlobalNotaryRegistryNotaryAddedIterator, error) { - logs, sub, err := _Initializable.contract.FilterLogs(opts, "Initialized") + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.FilterLogs(opts, "NotaryAdded", domainRule) if err != nil { return nil, err } - return &InitializableInitializedIterator{contract: _Initializable.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &GlobalNotaryRegistryNotaryAddedIterator{contract: _GlobalNotaryRegistry.contract, event: "NotaryAdded", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchNotaryAdded is a free log subscription operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *InitializableInitialized) (event.Subscription, error) { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) WatchNotaryAdded(opts *bind.WatchOpts, sink chan<- *GlobalNotaryRegistryNotaryAdded, domain []uint32) (event.Subscription, error) { - logs, sub, err := _Initializable.contract.WatchLogs(opts, "Initialized") + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.WatchLogs(opts, "NotaryAdded", domainRule) if err != nil { return nil, err } @@ -2728,8 +2761,8 @@ func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOp select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(InitializableInitialized) - if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(GlobalNotaryRegistryNotaryAdded) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryAdded", log); err != nil { return err } event.Raw = log @@ -2750,194 +2783,21 @@ func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOp }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseNotaryAdded is a log parse operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*InitializableInitialized, error) { - event := new(InitializableInitialized) - if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) ParseNotaryAdded(log types.Log) (*GlobalNotaryRegistryNotaryAdded, error) { + event := new(GlobalNotaryRegistryNotaryAdded) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -// NotaryRegistryMetaData contains all meta data concerning the NotaryRegistry contract. -var NotaryRegistryMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"}]", - Bin: "0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220a3a24aa9797da5ab584e8a150e23f1ff4388cf90cf9573a4719eb0ac78e37fad64736f6c634300080d0033", -} - -// NotaryRegistryABI is the input ABI used to generate the binding from. -// Deprecated: Use NotaryRegistryMetaData.ABI instead. -var NotaryRegistryABI = NotaryRegistryMetaData.ABI - -// NotaryRegistryBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use NotaryRegistryMetaData.Bin instead. -var NotaryRegistryBin = NotaryRegistryMetaData.Bin - -// DeployNotaryRegistry deploys a new Ethereum contract, binding an instance of NotaryRegistry to it. -func DeployNotaryRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *NotaryRegistry, error) { - parsed, err := NotaryRegistryMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NotaryRegistryBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &NotaryRegistry{NotaryRegistryCaller: NotaryRegistryCaller{contract: contract}, NotaryRegistryTransactor: NotaryRegistryTransactor{contract: contract}, NotaryRegistryFilterer: NotaryRegistryFilterer{contract: contract}}, nil -} - -// NotaryRegistry is an auto generated Go binding around an Ethereum contract. -type NotaryRegistry struct { - NotaryRegistryCaller // Read-only binding to the contract - NotaryRegistryTransactor // Write-only binding to the contract - NotaryRegistryFilterer // Log filterer for contract events -} - -// NotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. -type NotaryRegistryCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// NotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. -type NotaryRegistryTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// NotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type NotaryRegistryFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// NotaryRegistrySession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type NotaryRegistrySession struct { - Contract *NotaryRegistry // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// NotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type NotaryRegistryCallerSession struct { - Contract *NotaryRegistryCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// NotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type NotaryRegistryTransactorSession struct { - Contract *NotaryRegistryTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// NotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. -type NotaryRegistryRaw struct { - Contract *NotaryRegistry // Generic contract binding to access the raw methods on -} - -// NotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type NotaryRegistryCallerRaw struct { - Contract *NotaryRegistryCaller // Generic read-only contract binding to access the raw methods on -} - -// NotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type NotaryRegistryTransactorRaw struct { - Contract *NotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewNotaryRegistry creates a new instance of NotaryRegistry, bound to a specific deployed contract. -func NewNotaryRegistry(address common.Address, backend bind.ContractBackend) (*NotaryRegistry, error) { - contract, err := bindNotaryRegistry(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &NotaryRegistry{NotaryRegistryCaller: NotaryRegistryCaller{contract: contract}, NotaryRegistryTransactor: NotaryRegistryTransactor{contract: contract}, NotaryRegistryFilterer: NotaryRegistryFilterer{contract: contract}}, nil -} - -// NewNotaryRegistryCaller creates a new read-only instance of NotaryRegistry, bound to a specific deployed contract. -func NewNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*NotaryRegistryCaller, error) { - contract, err := bindNotaryRegistry(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &NotaryRegistryCaller{contract: contract}, nil -} - -// NewNotaryRegistryTransactor creates a new write-only instance of NotaryRegistry, bound to a specific deployed contract. -func NewNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*NotaryRegistryTransactor, error) { - contract, err := bindNotaryRegistry(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &NotaryRegistryTransactor{contract: contract}, nil -} - -// NewNotaryRegistryFilterer creates a new log filterer instance of NotaryRegistry, bound to a specific deployed contract. -func NewNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*NotaryRegistryFilterer, error) { - contract, err := bindNotaryRegistry(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &NotaryRegistryFilterer{contract: contract}, nil -} - -// bindNotaryRegistry binds a generic wrapper to an already deployed contract. -func bindNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(NotaryRegistryABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_NotaryRegistry *NotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _NotaryRegistry.Contract.NotaryRegistryCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_NotaryRegistry *NotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _NotaryRegistry.Contract.NotaryRegistryTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_NotaryRegistry *NotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _NotaryRegistry.Contract.NotaryRegistryTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_NotaryRegistry *NotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _NotaryRegistry.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_NotaryRegistry *NotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _NotaryRegistry.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_NotaryRegistry *NotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _NotaryRegistry.Contract.contract.Transact(opts, method, params...) -} - -// NotaryRegistryNotaryAddedIterator is returned from FilterNotaryAdded and is used to iterate over the raw logs and unpacked data for NotaryAdded events raised by the NotaryRegistry contract. -type NotaryRegistryNotaryAddedIterator struct { - Event *NotaryRegistryNotaryAdded // Event containing the contract specifics and raw log +// GlobalNotaryRegistryNotaryRemovedIterator is returned from FilterNotaryRemoved and is used to iterate over the raw logs and unpacked data for NotaryRemoved events raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryRemovedIterator struct { + Event *GlobalNotaryRegistryNotaryRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2951,7 +2811,7 @@ type NotaryRegistryNotaryAddedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *NotaryRegistryNotaryAddedIterator) Next() bool { +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2960,7 +2820,7 @@ func (it *NotaryRegistryNotaryAddedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(NotaryRegistryNotaryAdded) + it.Event = new(GlobalNotaryRegistryNotaryRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2975,7 +2835,7 @@ func (it *NotaryRegistryNotaryAddedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(NotaryRegistryNotaryAdded) + it.Event = new(GlobalNotaryRegistryNotaryRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2991,52 +2851,52 @@ func (it *NotaryRegistryNotaryAddedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *NotaryRegistryNotaryAddedIterator) Error() error { +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *NotaryRegistryNotaryAddedIterator) Close() error { +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// NotaryRegistryNotaryAdded represents a NotaryAdded event raised by the NotaryRegistry contract. -type NotaryRegistryNotaryAdded struct { +// GlobalNotaryRegistryNotaryRemoved represents a NotaryRemoved event raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryRemoved struct { Domain uint32 Notary common.Address Raw types.Log // Blockchain specific contextual infos } -// FilterNotaryAdded is a free log retrieval operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// FilterNotaryRemoved is a free log retrieval operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event NotaryAdded(uint32 indexed domain, address notary) -func (_NotaryRegistry *NotaryRegistryFilterer) FilterNotaryAdded(opts *bind.FilterOpts, domain []uint32) (*NotaryRegistryNotaryAddedIterator, error) { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) FilterNotaryRemoved(opts *bind.FilterOpts, domain []uint32) (*GlobalNotaryRegistryNotaryRemovedIterator, error) { var domainRule []interface{} for _, domainItem := range domain { domainRule = append(domainRule, domainItem) } - logs, sub, err := _NotaryRegistry.contract.FilterLogs(opts, "NotaryAdded", domainRule) + logs, sub, err := _GlobalNotaryRegistry.contract.FilterLogs(opts, "NotaryRemoved", domainRule) if err != nil { return nil, err } - return &NotaryRegistryNotaryAddedIterator{contract: _NotaryRegistry.contract, event: "NotaryAdded", logs: logs, sub: sub}, nil + return &GlobalNotaryRegistryNotaryRemovedIterator{contract: _GlobalNotaryRegistry.contract, event: "NotaryRemoved", logs: logs, sub: sub}, nil } -// WatchNotaryAdded is a free log subscription operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// WatchNotaryRemoved is a free log subscription operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event NotaryAdded(uint32 indexed domain, address notary) -func (_NotaryRegistry *NotaryRegistryFilterer) WatchNotaryAdded(opts *bind.WatchOpts, sink chan<- *NotaryRegistryNotaryAdded, domain []uint32) (event.Subscription, error) { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) WatchNotaryRemoved(opts *bind.WatchOpts, sink chan<- *GlobalNotaryRegistryNotaryRemoved, domain []uint32) (event.Subscription, error) { var domainRule []interface{} for _, domainItem := range domain { domainRule = append(domainRule, domainItem) } - logs, sub, err := _NotaryRegistry.contract.WatchLogs(opts, "NotaryAdded", domainRule) + logs, sub, err := _GlobalNotaryRegistry.contract.WatchLogs(opts, "NotaryRemoved", domainRule) if err != nil { return nil, err } @@ -3046,8 +2906,8 @@ func (_NotaryRegistry *NotaryRegistryFilterer) WatchNotaryAdded(opts *bind.Watch select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(NotaryRegistryNotaryAdded) - if err := _NotaryRegistry.contract.UnpackLog(event, "NotaryAdded", log); err != nil { + event := new(GlobalNotaryRegistryNotaryRemoved) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { return err } event.Raw = log @@ -3068,21 +2928,172 @@ func (_NotaryRegistry *NotaryRegistryFilterer) WatchNotaryAdded(opts *bind.Watch }), nil } -// ParseNotaryAdded is a log parse operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// ParseNotaryRemoved is a log parse operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event NotaryAdded(uint32 indexed domain, address notary) -func (_NotaryRegistry *NotaryRegistryFilterer) ParseNotaryAdded(log types.Log) (*NotaryRegistryNotaryAdded, error) { - event := new(NotaryRegistryNotaryAdded) - if err := _NotaryRegistry.contract.UnpackLog(event, "NotaryAdded", log); err != nil { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) ParseNotaryRemoved(log types.Log) (*GlobalNotaryRegistryNotaryRemoved, error) { + event := new(GlobalNotaryRegistryNotaryRemoved) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// NotaryRegistryNotaryRemovedIterator is returned from FilterNotaryRemoved and is used to iterate over the raw logs and unpacked data for NotaryRemoved events raised by the NotaryRegistry contract. -type NotaryRegistryNotaryRemovedIterator struct { - Event *NotaryRegistryNotaryRemoved // Event containing the contract specifics and raw log +// InitializableMetaData contains all meta data concerning the Initializable contract. +var InitializableMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", +} + +// InitializableABI is the input ABI used to generate the binding from. +// Deprecated: Use InitializableMetaData.ABI instead. +var InitializableABI = InitializableMetaData.ABI + +// Initializable is an auto generated Go binding around an Ethereum contract. +type Initializable struct { + InitializableCaller // Read-only binding to the contract + InitializableTransactor // Write-only binding to the contract + InitializableFilterer // Log filterer for contract events +} + +// InitializableCaller is an auto generated read-only Go binding around an Ethereum contract. +type InitializableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InitializableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type InitializableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InitializableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type InitializableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InitializableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type InitializableSession struct { + Contract *Initializable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InitializableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type InitializableCallerSession struct { + Contract *InitializableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// InitializableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type InitializableTransactorSession struct { + Contract *InitializableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InitializableRaw is an auto generated low-level Go binding around an Ethereum contract. +type InitializableRaw struct { + Contract *Initializable // Generic contract binding to access the raw methods on +} + +// InitializableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type InitializableCallerRaw struct { + Contract *InitializableCaller // Generic read-only contract binding to access the raw methods on +} + +// InitializableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type InitializableTransactorRaw struct { + Contract *InitializableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewInitializable creates a new instance of Initializable, bound to a specific deployed contract. +func NewInitializable(address common.Address, backend bind.ContractBackend) (*Initializable, error) { + contract, err := bindInitializable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Initializable{InitializableCaller: InitializableCaller{contract: contract}, InitializableTransactor: InitializableTransactor{contract: contract}, InitializableFilterer: InitializableFilterer{contract: contract}}, nil +} + +// NewInitializableCaller creates a new read-only instance of Initializable, bound to a specific deployed contract. +func NewInitializableCaller(address common.Address, caller bind.ContractCaller) (*InitializableCaller, error) { + contract, err := bindInitializable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &InitializableCaller{contract: contract}, nil +} + +// NewInitializableTransactor creates a new write-only instance of Initializable, bound to a specific deployed contract. +func NewInitializableTransactor(address common.Address, transactor bind.ContractTransactor) (*InitializableTransactor, error) { + contract, err := bindInitializable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &InitializableTransactor{contract: contract}, nil +} + +// NewInitializableFilterer creates a new log filterer instance of Initializable, bound to a specific deployed contract. +func NewInitializableFilterer(address common.Address, filterer bind.ContractFilterer) (*InitializableFilterer, error) { + contract, err := bindInitializable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &InitializableFilterer{contract: contract}, nil +} + +// bindInitializable binds a generic wrapper to an already deployed contract. +func bindInitializable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(InitializableABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Initializable *InitializableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Initializable.Contract.InitializableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Initializable *InitializableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Initializable.Contract.InitializableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Initializable *InitializableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Initializable.Contract.InitializableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Initializable *InitializableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Initializable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Initializable *InitializableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Initializable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Initializable *InitializableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Initializable.Contract.contract.Transact(opts, method, params...) +} + +// InitializableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Initializable contract. +type InitializableInitializedIterator struct { + Event *InitializableInitialized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -3096,7 +3107,7 @@ type NotaryRegistryNotaryRemovedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *NotaryRegistryNotaryRemovedIterator) Next() bool { +func (it *InitializableInitializedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -3105,7 +3116,7 @@ func (it *NotaryRegistryNotaryRemovedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(NotaryRegistryNotaryRemoved) + it.Event = new(InitializableInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3120,7 +3131,7 @@ func (it *NotaryRegistryNotaryRemovedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(NotaryRegistryNotaryRemoved) + it.Event = new(InitializableInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3136,52 +3147,41 @@ func (it *NotaryRegistryNotaryRemovedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *NotaryRegistryNotaryRemovedIterator) Error() error { +func (it *InitializableInitializedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *NotaryRegistryNotaryRemovedIterator) Close() error { +func (it *InitializableInitializedIterator) Close() error { it.sub.Unsubscribe() return nil } -// NotaryRegistryNotaryRemoved represents a NotaryRemoved event raised by the NotaryRegistry contract. -type NotaryRegistryNotaryRemoved struct { - Domain uint32 - Notary common.Address - Raw types.Log // Blockchain specific contextual infos +// InitializableInitialized represents a Initialized event raised by the Initializable contract. +type InitializableInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// FilterNotaryRemoved is a free log retrieval operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) -func (_NotaryRegistry *NotaryRegistryFilterer) FilterNotaryRemoved(opts *bind.FilterOpts, domain []uint32) (*NotaryRegistryNotaryRemovedIterator, error) { - - var domainRule []interface{} - for _, domainItem := range domain { - domainRule = append(domainRule, domainItem) - } +// Solidity: event Initialized(uint8 version) +func (_Initializable *InitializableFilterer) FilterInitialized(opts *bind.FilterOpts) (*InitializableInitializedIterator, error) { - logs, sub, err := _NotaryRegistry.contract.FilterLogs(opts, "NotaryRemoved", domainRule) + logs, sub, err := _Initializable.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &NotaryRegistryNotaryRemovedIterator{contract: _NotaryRegistry.contract, event: "NotaryRemoved", logs: logs, sub: sub}, nil + return &InitializableInitializedIterator{contract: _Initializable.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// WatchNotaryRemoved is a free log subscription operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) -func (_NotaryRegistry *NotaryRegistryFilterer) WatchNotaryRemoved(opts *bind.WatchOpts, sink chan<- *NotaryRegistryNotaryRemoved, domain []uint32) (event.Subscription, error) { - - var domainRule []interface{} - for _, domainItem := range domain { - domainRule = append(domainRule, domainItem) - } +// Solidity: event Initialized(uint8 version) +func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *InitializableInitialized) (event.Subscription, error) { - logs, sub, err := _NotaryRegistry.contract.WatchLogs(opts, "NotaryRemoved", domainRule) + logs, sub, err := _Initializable.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } @@ -3191,8 +3191,8 @@ func (_NotaryRegistry *NotaryRegistryFilterer) WatchNotaryRemoved(opts *bind.Wat select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(NotaryRegistryNotaryRemoved) - if err := _NotaryRegistry.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { + event := new(InitializableInitialized) + if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { return err } event.Raw = log @@ -3213,12 +3213,12 @@ func (_NotaryRegistry *NotaryRegistryFilterer) WatchNotaryRemoved(opts *bind.Wat }), nil } -// ParseNotaryRemoved is a log parse operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) -func (_NotaryRegistry *NotaryRegistryFilterer) ParseNotaryRemoved(log types.Log) (*NotaryRegistryNotaryRemoved, error) { - event := new(NotaryRegistryNotaryRemoved) - if err := _NotaryRegistry.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { +// Solidity: event Initialized(uint8 version) +func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*InitializableInitialized, error) { + event := new(InitializableInitialized) + if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } event.Raw = log @@ -3748,7 +3748,7 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred // StringsMetaData contains all meta data concerning the Strings contract. var StringsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204b3b65680f5c760942b2153fb8c40b355f26a840c28b6079f9365abda9d4985b64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220687bf7039c5fb2337b63cd86b08f4e2ae50fa16744632f24bb6a74d66089df5f64736f6c634300080d0033", } // StringsABI is the input ABI used to generate the binding from. @@ -3924,7 +3924,7 @@ var TypedMemViewMetaData = &bind.MetaData{ Sigs: map[string]string{ "f26be3fc": "NULL()", }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220506cedf33a125f7290e6fd62dcbafe680f2917ad85961fec39783b466cb7807864736f6c634300080d0033", + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122053e5d99f61b8f90af9348cc4f350db2318a784e1ec61d0a8450bdc58d9da9ffc64736f6c634300080d0033", } // TypedMemViewABI is the input ABI used to generate the binding from. diff --git a/core/contracts/attestationcollector/attestationcollector.contractinfo.json b/core/contracts/attestationcollector/attestationcollector.contractinfo.json index 7b12c6cae2..19783704c2 100644 --- a/core/contracts/attestationcollector/attestationcollector.contractinfo.json +++ b/core/contracts/attestationcollector/attestationcollector.contractinfo.json @@ -1 +1 @@ -{"solidity/AttestationCollector.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205130aff3af56b954e70d84f1f71053f5fc7fc4bbbdc98965c9cb5de6af4f96ec64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205130aff3af56b954e70d84f1f71053f5fc7fc4bbbdc98965c9cb5de6af4f96ec64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"55045:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;55045:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"55045:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206e0abd69af18e5e395d1508ee8761beefbf7b753a40677f7fc409c34d1640e6664736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206e0abd69af18e5e395d1508ee8761beefbf7b753a40677f7fc409c34d1640e6664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32270:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32270:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32270:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:AttestationCollector":{"code":"0x608060405234801561001057600080fd5b506127e1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638129fc1c11610097578063d451680311610066578063d4516803146101ec578063d53f2eec14610217578063f2fde38b1461025d578063f646a5121461027057600080fd5b80638129fc1c146101965780638da5cb5b1461019e578063a7d729bd146101c6578063bb07a791146101d957600080fd5b80634b82bad7116100d35780634b82bad714610148578063563ffbec1461015b578063715018a61461017b5780637eb2923f1461018357600080fd5b806317007970146100fa578063289def8d146101205780632af678b014610133575b600080fd5b61010d61010836600461223d565b610293565b6040519081526020015b60405180910390f35b61010d61012e366004612270565b6102bd565b6101466101413660046122d0565b61037e565b005b6101466101563660046122d0565b6103f4565b61016e610169366004612270565b610465565b6040516101179190612374565b6101466104d1565b61016e6101913660046122d0565b610544565b61014661061b565b60975460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b61016e6101d4366004612387565b6106ca565b61016e6101e7366004612270565b610865565b61010d6101fa3660046122d0565b60cc60209081526000928352604080842090915290825290205481565b6102486102253660046122d0565b60cb60209081526000928352604080842090915290825290205463ffffffff1681565b60405163ffffffff9091168152602001610117565b61014661026b3660046123a2565b610881565b61028361027e3660046123ec565b61097a565b6040519015158152602001610117565b63ffffffff808316600090815260c960209081526040808320938516835292905220545b92915050565b63ffffffff808416600090815260c96020908152604080832093861683529290529081205482106103355760405162461bcd60e51b815260206004820152600660248201527f21696e646578000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b63ffffffff808516600090815260c960209081526040808320938716835292905220805483908110610369576103696124bb565b906000526020600020015490505b9392505050565b60975473ffffffffffffffffffffffffffffffffffffffff1633146103e55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef82826109f4565b505050565b60975473ffffffffffffffffffffffffffffffffffffffff16331461045b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef8282610af1565b6060610472848484610d1a565b6104be5760405162461bcd60e51b815260206004820152600a60248201527f217369676e617475726500000000000000000000000000000000000000000000604482015260640161032c565b6104c9848484610d60565b949350505050565b60975473ffffffffffffffffffffffffffffffffffffffff1633146105385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6105426000610e73565b565b63ffffffff808316600090815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205460609216908190036105d05760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b63ffffffff8416600090815260cc6020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610612858383610d60565b95945050505050565b60006106276001610eea565b9050801561065c57606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610664611043565b80156106c757606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b63ffffffff81166000908152603260205260408120546060918190036107325760405162461bcd60e51b815260206004820152600960248201527f216e6f7461726965730000000000000000000000000000000000000000000000604482015260640161032c565b600080805b838110156108035763ffffffff86166000908152603260205260408120805483908110610766576107666124bb565b600091825260208083209091015463ffffffff808b16845260cb8352604080852073ffffffffffffffffffffffffffffffffffffffff9093168086529290935291909220549192509081169085168111156107f95763ffffffff8816600090815260cc6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020549094509250835b5050600101610737565b508163ffffffff1660000361085a5760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b610612858383610d60565b606060006108748585856102bd565b9050610612858583610d60565b60975473ffffffffffffffffffffffffffffffffffffffff1633146108e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b73ffffffffffffffffffffffffffffffffffffffff81166109715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161032c565b6106c781610e73565b6000806000610988846110c9565b9150915061099682826111d9565b925082156109ed578173ffffffffffffffffffffffffffffffffffffffff167f786431104fc3c4b19da7bae78f422f46b9c07528276a2ee430e8569cb8705f14856040516109e49190612374565b60405180910390a25b5050919050565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415610a38575060006102b7565b63ffffffff8316600081815260326020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546033845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054808203610b395760009150506102b7565b63ffffffff8416600090815260326020526040812090610b5a600184612519565b8254909150600090610b6e90600190612519565b9050818114610c3a576000838281548110610b8b57610b8b6124bb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080848481548110610bcb57610bcb6124bb565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94851617905563ffffffff8b1682526033815260408083209490931682529290925290208490555b82805480610c4a57610c4a612530565b600082815260208082207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908401810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925563ffffffff891680835260338252604080842073ffffffffffffffffffffffffffffffffffffffff8b168086529084528185209490945551928352917f3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b910160405180910390a25060019695505050505050565b63ffffffff808416600090815260ca60209081526040808320938616835292815282822084835290529081208054829190610d549061255f565b90501190509392505050565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086811b8216602084015285901b16602482015260288082018490528251808303909101815260489091019091526060906104c99063ffffffff808716600090815260ca6020908152604080832093891683529281528282208783529052208054610df09061255f565b80601f0160208091040260200160405190810160405280929190818152602001828054610e1c9061255f565b8015610e695780601f10610e3e57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610e4c57829003601f168201915b50505050506113c9565b6097805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606454600090610100900460ff1615610f89578160ff166001148015610f0f5750303b155b610f815760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b506000919050565b60645460ff8084169116106110065760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b50606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b606454610100900460ff166110c05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161032c565b61054233610e73565b6000806110d683826113f5565b905060286bffffffffffffffffffffffff601883901c161161113a5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161032c565b61116e61114c62ffffff198316611410565b61116961115e62ffffff198516611425565b62ffffff1916611458565b6114ab565b915061118861118262ffffff198316611522565b83611536565b6111d45760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161032c565b915091565b6000806111eb62ffffff198416611522565b905060006111fe62ffffff198516611574565b9050600061121162ffffff198616611588565b63ffffffff808516600090815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1684529091529020549192509081169083161161129f5760405162461bcd60e51b815260206004820152601460248201527f4f75746461746564206174746573746174696f6e000000000000000000000000604482015260640161032c565b6112aa838383610d1a565b156112bb57600093505050506102b7565b63ffffffff838116600081815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000169689169690961790955592825260cc815282822093825292909252902081905561134a61115e62ffffff198716611425565b63ffffffff808516600090815260ca602090815260408083209387168352928152828220858352815291902082516113889391929190910190612190565b5063ffffffff928316600090815260c96020908152604080832094909516825292835292832080546001808201835591855292909320909101559392505050565b606082826040516020016113de9291906125ac565b604051602081830303815290604052905092915050565b81516000906020840161061264ffffffffff8516828461159d565b60006102b762ffffff198316826028816115e2565b60006102b7602861144881601886901c6bffffffffffffffffffffffff16612519565b62ffffff198516919060006115e2565b60606000806114758460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050604051915081925061149a8483602001611666565b508181016020016040529052919050565b6000806114bd62ffffff198516611801565b9050611516816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506104c9818461185e565b60006102b762ffffff198316826004611882565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091528120541515610377565b60006102b762ffffff198316600480611882565b60006102b762ffffff198316600860206118b2565b6000806115aa83856125db565b90506040518111156115ba575060005b806000036115cf5762ffffff19915050610377565b606085811b8517901b831760181b610612565b6000806115fd8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061161686611a70565b8461162187846125db565b61162b91906125db565b111561163e5762ffffff199150506104c9565b61164885826125db565b905061165c8364ffffffffff16828661159d565b9695505050505050565b600062ffffff19808416036116e35760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161032c565b6116ec83611ab8565b61175e5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161032c565b60006117788460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006117a28560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156117c75760206060fd5b8285848460045afa5061165c6117dd8760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b60008061181c8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006118468460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061186d8585611af5565b9150915061187a81611b63565b509392505050565b600061188f8260206125f3565b61189a906008612616565b60ff166118a88585856118b2565b901c949350505050565b60008160ff166000036118c757506000610377565b6118df8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118fa60ff8416856125db565b11156119725761195961191b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119418660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16611d4f565b60405162461bcd60e51b815260040161032c9190612374565b60208260ff1611156119ec5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161032c565b600882026000611a0a8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000611a8a8260181c6bffffffffffffffffffffffff1690565b611aa28360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000611ac48260d81c90565b64ffffffffff1664ffffffffff03611ade57506000919050565b6000611ae983611a70565b60405110199392505050565b6000808251604103611b2b5760208301516040840151606085015160001a611b1f87828585611dbd565b94509450505050611b5c565b8251604003611b545760208301516040840151611b49868383611ed5565b935093505050611b5c565b506000905060025b9250929050565b6000816004811115611b7757611b7761263f565b03611b7f5750565b6001816004811115611b9357611b9361263f565b03611be05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161032c565b6002816004811115611bf457611bf461263f565b03611c415760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161032c565b6003816004811115611c5557611c5561263f565b03611cc85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b6004816004811115611cdc57611cdc61263f565b036106c75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b60606000611d5c86611f27565b9150506000611d6a86611f27565b9150506000611d7886611f27565b9150506000611d8686611f27565b91505083838383604051602001611da0949392919061266e565b604051602081830303815290604052945050505050949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611df45750600090506003611ecc565b8460ff16601b14158015611e0c57508460ff16601c14155b15611e1d5750600090506004611ecc565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e71573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611ec557600060019250925050611ecc565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681611f0b60ff86901c601b6125db565b9050611f1987828885611dbd565b935093505050935093915050565b600080601f5b600f8160ff161115611f9a576000611f46826008612616565b60ff1685901c9050611f5781612011565b61ffff16841793508160ff16601014611f7257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f2d565b50600f5b60ff8160ff16101561200b576000611fb7826008612616565b60ff1685901c9050611fc881612011565b61ffff16831792508160ff16600014611fe357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f9e565b50915091565b600061202360048360ff16901c612043565b60ff1661ffff919091161760081b61203a82612043565b60ff1617919050565b600060f08083179060ff8216900361205e5750603092915050565b8060ff1660f1036120725750603192915050565b8060ff1660f2036120865750603292915050565b8060ff1660f30361209a5750603392915050565b8060ff1660f4036120ae5750603492915050565b8060ff1660f5036120c25750603592915050565b8060ff1660f6036120d65750603692915050565b8060ff1660f7036120ea5750603792915050565b8060ff1660f8036120fe5750603892915050565b8060ff1660f9036121125750603992915050565b8060ff1660fa036121265750606192915050565b8060ff1660fb0361213a5750606292915050565b8060ff1660fc0361214e5750606392915050565b8060ff1660fd036121625750606492915050565b8060ff1660fe036121765750606592915050565b8060ff1660ff0361218a5750606692915050565b50919050565b82805461219c9061255f565b90600052602060002090601f0160209004810192826121be5760008555612204565b82601f106121d757805160ff1916838001178555612204565b82800160010185558215612204579182015b828111156122045782518255916020019190600101906121e9565b50612210929150612214565b5090565b5b808211156122105760008155600101612215565b803563ffffffff8116811461103e57600080fd5b6000806040838503121561225057600080fd5b61225983612229565b915061226760208401612229565b90509250929050565b60008060006060848603121561228557600080fd5b61228e84612229565b925061229c60208501612229565b9150604084013590509250925092565b803573ffffffffffffffffffffffffffffffffffffffff8116811461103e57600080fd5b600080604083850312156122e357600080fd5b6122ec83612229565b9150612267602084016122ac565b60005b838110156123155781810151838201526020016122fd565b83811115612324576000848401525b50505050565b600081518084526123428160208601602086016122fa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610377602083018461232a565b60006020828403121561239957600080fd5b61037782612229565b6000602082840312156123b457600080fd5b610377826122ac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156123fe57600080fd5b813567ffffffffffffffff8082111561241657600080fd5b818401915084601f83011261242a57600080fd5b81358181111561243c5761243c6123bd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612482576124826123bd565b8160405282815287602084870101111561249b57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561252b5761252b6124ea565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600181811c9082168061257357607f821691505b60208210810361218a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600083516125be8184602088016122fa565b8351908301906125d28183602088016122fa565b01949350505050565b600082198211156125ee576125ee6124ea565b500190565b600060ff821660ff84168082101561260d5761260d6124ea565b90039392505050565b600060ff821660ff84168160ff0481118215151615612637576126376124ea565b029392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161165c56fea2646970667358221220d5c9d5ae9e7ee85d4eaa5a58fd7d248f12b96317130c56c1dfa25865fd224ff864736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80638129fc1c11610097578063d451680311610066578063d4516803146101ec578063d53f2eec14610217578063f2fde38b1461025d578063f646a5121461027057600080fd5b80638129fc1c146101965780638da5cb5b1461019e578063a7d729bd146101c6578063bb07a791146101d957600080fd5b80634b82bad7116100d35780634b82bad714610148578063563ffbec1461015b578063715018a61461017b5780637eb2923f1461018357600080fd5b806317007970146100fa578063289def8d146101205780632af678b014610133575b600080fd5b61010d61010836600461223d565b610293565b6040519081526020015b60405180910390f35b61010d61012e366004612270565b6102bd565b6101466101413660046122d0565b61037e565b005b6101466101563660046122d0565b6103f4565b61016e610169366004612270565b610465565b6040516101179190612374565b6101466104d1565b61016e6101913660046122d0565b610544565b61014661061b565b60975460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b61016e6101d4366004612387565b6106ca565b61016e6101e7366004612270565b610865565b61010d6101fa3660046122d0565b60cc60209081526000928352604080842090915290825290205481565b6102486102253660046122d0565b60cb60209081526000928352604080842090915290825290205463ffffffff1681565b60405163ffffffff9091168152602001610117565b61014661026b3660046123a2565b610881565b61028361027e3660046123ec565b61097a565b6040519015158152602001610117565b63ffffffff808316600090815260c960209081526040808320938516835292905220545b92915050565b63ffffffff808416600090815260c96020908152604080832093861683529290529081205482106103355760405162461bcd60e51b815260206004820152600660248201527f21696e646578000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b63ffffffff808516600090815260c960209081526040808320938716835292905220805483908110610369576103696124bb565b906000526020600020015490505b9392505050565b60975473ffffffffffffffffffffffffffffffffffffffff1633146103e55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef82826109f4565b505050565b60975473ffffffffffffffffffffffffffffffffffffffff16331461045b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef8282610af1565b6060610472848484610d1a565b6104be5760405162461bcd60e51b815260206004820152600a60248201527f217369676e617475726500000000000000000000000000000000000000000000604482015260640161032c565b6104c9848484610d60565b949350505050565b60975473ffffffffffffffffffffffffffffffffffffffff1633146105385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6105426000610e73565b565b63ffffffff808316600090815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205460609216908190036105d05760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b63ffffffff8416600090815260cc6020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610612858383610d60565b95945050505050565b60006106276001610eea565b9050801561065c57606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610664611043565b80156106c757606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b63ffffffff81166000908152603260205260408120546060918190036107325760405162461bcd60e51b815260206004820152600960248201527f216e6f7461726965730000000000000000000000000000000000000000000000604482015260640161032c565b600080805b838110156108035763ffffffff86166000908152603260205260408120805483908110610766576107666124bb565b600091825260208083209091015463ffffffff808b16845260cb8352604080852073ffffffffffffffffffffffffffffffffffffffff9093168086529290935291909220549192509081169085168111156107f95763ffffffff8816600090815260cc6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020549094509250835b5050600101610737565b508163ffffffff1660000361085a5760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b610612858383610d60565b606060006108748585856102bd565b9050610612858583610d60565b60975473ffffffffffffffffffffffffffffffffffffffff1633146108e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b73ffffffffffffffffffffffffffffffffffffffff81166109715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161032c565b6106c781610e73565b6000806000610988846110c9565b9150915061099682826111d9565b925082156109ed578173ffffffffffffffffffffffffffffffffffffffff167f786431104fc3c4b19da7bae78f422f46b9c07528276a2ee430e8569cb8705f14856040516109e49190612374565b60405180910390a25b5050919050565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415610a38575060006102b7565b63ffffffff8316600081815260326020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546033845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054808203610b395760009150506102b7565b63ffffffff8416600090815260326020526040812090610b5a600184612519565b8254909150600090610b6e90600190612519565b9050818114610c3a576000838281548110610b8b57610b8b6124bb565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080848481548110610bcb57610bcb6124bb565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94851617905563ffffffff8b1682526033815260408083209490931682529290925290208490555b82805480610c4a57610c4a612530565b600082815260208082207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908401810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925563ffffffff891680835260338252604080842073ffffffffffffffffffffffffffffffffffffffff8b168086529084528185209490945551928352917f3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b910160405180910390a25060019695505050505050565b63ffffffff808416600090815260ca60209081526040808320938616835292815282822084835290529081208054829190610d549061255f565b90501190509392505050565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086811b8216602084015285901b16602482015260288082018490528251808303909101815260489091019091526060906104c99063ffffffff808716600090815260ca6020908152604080832093891683529281528282208783529052208054610df09061255f565b80601f0160208091040260200160405190810160405280929190818152602001828054610e1c9061255f565b8015610e695780601f10610e3e57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610e4c57829003601f168201915b50505050506113c9565b6097805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b606454600090610100900460ff1615610f89578160ff166001148015610f0f5750303b155b610f815760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b506000919050565b60645460ff8084169116106110065760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b50606480547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b606454610100900460ff166110c05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161032c565b61054233610e73565b6000806110d683826113f5565b905060286bffffffffffffffffffffffff601883901c161161113a5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161032c565b61116e61114c62ffffff198316611410565b61116961115e62ffffff198516611425565b62ffffff1916611458565b6114ab565b915061118861118262ffffff198316611522565b83611536565b6111d45760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161032c565b915091565b6000806111eb62ffffff198416611522565b905060006111fe62ffffff198516611574565b9050600061121162ffffff198616611588565b63ffffffff808516600090815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1684529091529020549192509081169083161161129f5760405162461bcd60e51b815260206004820152601460248201527f4f75746461746564206174746573746174696f6e000000000000000000000000604482015260640161032c565b6112aa838383610d1a565b156112bb57600093505050506102b7565b63ffffffff838116600081815260cb6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000169689169690961790955592825260cc815282822093825292909252902081905561134a61115e62ffffff198716611425565b63ffffffff808516600090815260ca602090815260408083209387168352928152828220858352815291902082516113889391929190910190612190565b5063ffffffff928316600090815260c96020908152604080832094909516825292835292832080546001808201835591855292909320909101559392505050565b606082826040516020016113de9291906125ac565b604051602081830303815290604052905092915050565b81516000906020840161061264ffffffffff8516828461159d565b60006102b762ffffff198316826028816115e2565b60006102b7602861144881601886901c6bffffffffffffffffffffffff16612519565b62ffffff198516919060006115e2565b60606000806114758460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050604051915081925061149a8483602001611666565b508181016020016040529052919050565b6000806114bd62ffffff198516611801565b9050611516816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506104c9818461185e565b60006102b762ffffff198316826004611882565b63ffffffff8216600090815260336020908152604080832073ffffffffffffffffffffffffffffffffffffffff851684529091528120541515610377565b60006102b762ffffff198316600480611882565b60006102b762ffffff198316600860206118b2565b6000806115aa83856125db565b90506040518111156115ba575060005b806000036115cf5762ffffff19915050610377565b606085811b8517901b831760181b610612565b6000806115fd8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061161686611a70565b8461162187846125db565b61162b91906125db565b111561163e5762ffffff199150506104c9565b61164885826125db565b905061165c8364ffffffffff16828661159d565b9695505050505050565b600062ffffff19808416036116e35760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161032c565b6116ec83611ab8565b61175e5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161032c565b60006117788460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006117a28560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156117c75760206060fd5b8285848460045afa5061165c6117dd8760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b60008061181c8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006118468460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061186d8585611af5565b9150915061187a81611b63565b509392505050565b600061188f8260206125f3565b61189a906008612616565b60ff166118a88585856118b2565b901c949350505050565b60008160ff166000036118c757506000610377565b6118df8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118fa60ff8416856125db565b11156119725761195961191b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119418660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16611d4f565b60405162461bcd60e51b815260040161032c9190612374565b60208260ff1611156119ec5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161032c565b600882026000611a0a8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000611a8a8260181c6bffffffffffffffffffffffff1690565b611aa28360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000611ac48260d81c90565b64ffffffffff1664ffffffffff03611ade57506000919050565b6000611ae983611a70565b60405110199392505050565b6000808251604103611b2b5760208301516040840151606085015160001a611b1f87828585611dbd565b94509450505050611b5c565b8251604003611b545760208301516040840151611b49868383611ed5565b935093505050611b5c565b506000905060025b9250929050565b6000816004811115611b7757611b7761263f565b03611b7f5750565b6001816004811115611b9357611b9361263f565b03611be05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161032c565b6002816004811115611bf457611bf461263f565b03611c415760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161032c565b6003816004811115611c5557611c5561263f565b03611cc85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b6004816004811115611cdc57611cdc61263f565b036106c75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b60606000611d5c86611f27565b9150506000611d6a86611f27565b9150506000611d7886611f27565b9150506000611d8686611f27565b91505083838383604051602001611da0949392919061266e565b604051602081830303815290604052945050505050949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611df45750600090506003611ecc565b8460ff16601b14158015611e0c57508460ff16601c14155b15611e1d5750600090506004611ecc565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e71573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611ec557600060019250925050611ecc565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681611f0b60ff86901c601b6125db565b9050611f1987828885611dbd565b935093505050935093915050565b600080601f5b600f8160ff161115611f9a576000611f46826008612616565b60ff1685901c9050611f5781612011565b61ffff16841793508160ff16601014611f7257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f2d565b50600f5b60ff8160ff16101561200b576000611fb7826008612616565b60ff1685901c9050611fc881612011565b61ffff16831792508160ff16600014611fe357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f9e565b50915091565b600061202360048360ff16901c612043565b60ff1661ffff919091161760081b61203a82612043565b60ff1617919050565b600060f08083179060ff8216900361205e5750603092915050565b8060ff1660f1036120725750603192915050565b8060ff1660f2036120865750603292915050565b8060ff1660f30361209a5750603392915050565b8060ff1660f4036120ae5750603492915050565b8060ff1660f5036120c25750603592915050565b8060ff1660f6036120d65750603692915050565b8060ff1660f7036120ea5750603792915050565b8060ff1660f8036120fe5750603892915050565b8060ff1660f9036121125750603992915050565b8060ff1660fa036121265750606192915050565b8060ff1660fb0361213a5750606292915050565b8060ff1660fc0361214e5750606392915050565b8060ff1660fd036121625750606492915050565b8060ff1660fe036121765750606592915050565b8060ff1660ff0361218a5750606692915050565b50919050565b82805461219c9061255f565b90600052602060002090601f0160209004810192826121be5760008555612204565b82601f106121d757805160ff1916838001178555612204565b82800160010185558215612204579182015b828111156122045782518255916020019190600101906121e9565b50612210929150612214565b5090565b5b808211156122105760008155600101612215565b803563ffffffff8116811461103e57600080fd5b6000806040838503121561225057600080fd5b61225983612229565b915061226760208401612229565b90509250929050565b60008060006060848603121561228557600080fd5b61228e84612229565b925061229c60208501612229565b9150604084013590509250925092565b803573ffffffffffffffffffffffffffffffffffffffff8116811461103e57600080fd5b600080604083850312156122e357600080fd5b6122ec83612229565b9150612267602084016122ac565b60005b838110156123155781810151838201526020016122fd565b83811115612324576000848401525b50505050565b600081518084526123428160208601602086016122fa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610377602083018461232a565b60006020828403121561239957600080fd5b61037782612229565b6000602082840312156123b457600080fd5b610377826122ac565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156123fe57600080fd5b813567ffffffffffffffff8082111561241657600080fd5b818401915084601f83011261242a57600080fd5b81358181111561243c5761243c6123bd565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612482576124826123bd565b8160405282815287602084870101111561249b57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561252b5761252b6124ea565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600181811c9082168061257357607f821691505b60208210810361218a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600083516125be8184602088016122fa565b8351908301906125d28183602088016122fa565b01949350505050565b600082198211156125ee576125ee6124ea565b500190565b600060ff821660ff84168082101561260d5761260d6124ea565b90039392505050565b600060ff821660ff84168160ff0481118215151615612637576126376124ea565b029392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161165c56fea2646970667358221220d5c9d5ae9e7ee85d4eaa5a58fd7d248f12b96317130c56c1dfa25865fd224ff864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"71720:11352:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"71720:11352:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79006:148;;;;;;:::i;:::-;;:::i;:::-;;;589:25:1;;;577:2;562:18;79006:148:0;;;;;;;;78551:267;;;;;;:::i;:::-;;:::i;79757:116::-;;;;;;:::i;:::-;;:::i;:::-;;79879:122;;;;;;:::i;:::-;;:::i;76605:276::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;70632:101::-;;;:::i;77952:353::-;;;;;;:::i;:::-;;:::i;75315:86::-;;;:::i;70000:85::-;70072:6;;70000:85;;70072:6;;;;2881:74:1;;2869:2;2854:18;70000:85:0;2735:226:1;76957:896:0;;;;;;:::i;:::-;;:::i;76201:313::-;;;;;;:::i;:::-;;:::i;74132:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;74016;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3329:10:1;3317:23;;;3299:42;;3287:2;3272:18;74016:64:0;3155:192:1;70882:198:0;;;;;;:::i;:::-;;:::i;80547:428::-;;;;;;:::i;:::-;;:::i;:::-;;;4882:14:1;;4875:22;4857:41;;4845:2;4830:18;80547:428:0;4717:187:1;79006:148:0;79107:25;;;;79081:7;79107:25;;;:16;:25;;;;;;;;:33;;;;;;;;;:40;79006:148;;;;;:::o;78551:267::-;78702:25;;;;78666:7;78702:25;;;:16;:25;;;;;;;;:33;;;;;;;;;;;:40;78693:49;;78685:68;;;;-1:-1:-1;;;78685:68:0;;5111:2:1;78685:68:0;;;5093:21:1;5150:1;5130:18;;;5123:29;5188:8;5168:18;;;5161:36;5214:18;;78685:68:0;;;;;;;;;78770:25;;;;;;;;:16;:25;;;;;;;;:33;;;;;;;;;:41;;78804:6;;78770:41;;;;;;:::i;:::-;;;;;;;;;78763:48;;78551:267;;;;;;:::o;79757:116::-;70072:6;;70212:23;70072:6;69000:10;70212:23;70204:68;;;;-1:-1:-1;;;70204:68:0;;5634:2:1;70204:68:0;;;5616:21:1;;;5653:18;;;5646:30;5712:34;5692:18;;;5685:62;5764:18;;70204:68:0;5432:356:1;70204:68:0;79838:28:::1;79849:7;79858;79838:10;:28::i;:::-;;79757:116:::0;;:::o;79879:122::-;70072:6;;70212:23;70072:6;69000:10;70212:23;70204:68;;;;-1:-1:-1;;;70204:68:0;;5634:2:1;70204:68:0;;;5616:21:1;;;5653:18;;;5646:30;5712:34;5692:18;;;5685:62;5764:18;;70204:68:0;5432:356:1;70204:68:0;79963:31:::1;79977:7;79986;79963:13;:31::i;76605:276::-:0;76728:12;76760:40;76777:7;76786:6;76794:5;76760:16;:40::i;:::-;76752:63;;;;-1:-1:-1;;;76752:63:0;;5995:2:1;76752:63:0;;;5977:21:1;6034:2;6014:18;;;6007:30;6073:12;6053:18;;;6046:40;6103:18;;76752:63:0;5793:334:1;76752:63:0;76832:42;76851:7;76860:6;76868:5;76832:18;:42::i;:::-;76825:49;76605:276;-1:-1:-1;;;;76605:276:0:o;70632:101::-;70072:6;;70212:23;70072:6;69000:10;70212:23;70204:68;;;;-1:-1:-1;;;70204:68:0;;5634:2:1;70204:68:0;;;5616:21:1;;;5653:18;;;5646:30;5712:34;5692:18;;;5685:62;5764:18;;70204:68:0;5432:356:1;70204:68:0;70696:30:::1;70723:1;70696:18;:30::i;:::-;70632:101::o:0;77952:353::-;78105:20;;;;78090:12;78105:20;;;:11;:20;;;;;;;;:29;;;;;;;;;;;78062:12;;78105:29;;78152:10;;;78144:44;;;;-1:-1:-1;;;78144:44:0;;6334:2:1;78144:44:0;;;6316:21:1;6373:2;6353:18;;;6346:30;6412:23;6392:18;;;6385:51;6453:18;;78144:44:0;6132:345:1;78144:44:0;78213:19;;;78198:12;78213:19;;;:10;:19;;;;;;;;:28;;;;;;;;;;;78258:40;78224:7;78286:5;78213:28;78258:18;:40::i;:::-;78251:47;77952:353;-1:-1:-1;;;;;77952:353:0:o;75315:86::-;65180:19;65202:25;65225:1;65202:22;:25::i;:::-;65180:47;;65241:14;65237:65;;;65271:13;:20;;;;;;;;65237:65;75368:26:::1;:24;:26::i;:::-;65326:14:::0;65322:99;;;65356:13;:21;;;;;;65396:14;;-1:-1:-1;6634:36:1;;65396:14:0;;6622:2:1;6607:18;65396:14:0;;;;;;;65322:99;65170:257;75315:86::o;76957:896::-;77075:23;;;77050:22;77075:23;;;:14;:23;;;;;:30;77026:12;;77123:19;;;77115:41;;;;-1:-1:-1;;;77115:41:0;;6883:2:1;77115:41:0;;;6865:21:1;6922:1;6902:18;;;6895:29;6960:11;6940:18;;;6933:39;6989:18;;77115:41:0;6681:332:1;77115:41:0;77166:19;;;77228:449;77252:14;77248:1;:18;77228:449;;;77301:23;;;77284:14;77301:23;;;:14;:23;;;;;:26;;77325:1;;77301:26;;;;;;:::i;:::-;;;;;;;;;;;;;77356:20;;;;;;:11;:20;;;;;;77301:26;;;;77356:28;;;;;;;;;;;;77301:26;;-1:-1:-1;77356:28:0;;;;77474:20;;;;77470:138;;;77528:19;;;;;;;:10;:19;;;;;;;;:27;;;;;;;;;;;77588:5;;-1:-1:-1;77528:27:0;-1:-1:-1;77588:5:0;77470:138;-1:-1:-1;;77649:3:0;;77228:449;;;;77732:12;:17;;77748:1;77732:17;77724:51;;;;-1:-1:-1;;;77724:51:0;;6334:2:1;77724:51:0;;;6316:21:1;6373:2;6353:18;;;6346:30;6412:23;6392:18;;;6385:51;6453:18;;77724:51:0;6132:345:1;77724:51:0;77792:54;77811:7;77820:12;77834:11;77792:18;:54::i;76201:313::-;76325:12;76349;76364:32;76372:7;76381:6;76389;76364:7;:32::i;:::-;76349:47;;76466:41;76485:7;76494:6;76502:4;76466:18;:41::i;70882:198::-;70072:6;;70212:23;70072:6;69000:10;70212:23;70204:68;;;;-1:-1:-1;;;70204:68:0;;5634:2:1;70204:68:0;;;5616:21:1;;;5653:18;;;5646:30;5712:34;5692:18;;;5685:62;5764:18;;70204:68:0;5432:356:1;70204:68:0;70970:22:::1;::::0;::::1;70962:73;;;::::0;-1:-1:-1;;;70962:73:0;;7220:2:1;70962:73:0::1;::::0;::::1;7202:21:1::0;7259:2;7239:18;;;7232:30;7298:34;7278:18;;;7271:62;7369:8;7349:18;;;7342:36;7395:19;;70962:73:0::1;7018:402:1::0;70962:73:0::1;71045:28;71064:8;71045:18;:28::i;80547:428::-:0;80635:22;80674:15;80691:13;80708:31;80726:12;80708:17;:31::i;:::-;80673:66;;;;80769:33;80787:7;80796:5;80769:17;:33::i;:::-;80749:53;;80816:17;80812:157;;;80936:7;80915:43;;;80945:12;80915:43;;;;;;:::i;:::-;;;;;;;;80812:157;80663:312;;80547:428;;;:::o;53417:327::-;53366:24;;;53488:4;53366:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;53504:45;;-1:-1:-1;53544:5:0;53537:12;;53504:45;53559:23;;;;;;;:14;:23;;;;;;;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;53642:23;;;:30;;53606:15;:24;;;;;:33;;;;;;;;;:66;;;;53687:29;2881:74:1;;;53687:29:0;;2854:18:1;53687:29:0;;;;;;;-1:-1:-1;53733:4:0;53417:327;;;;:::o;53750:1151::-;53861:24;;;53824:4;53861:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;53908:15;;;53904:33;;53932:5;53925:12;;;;;53904:33;54172:23;;;54143:26;54172:23;;;:14;:23;;;;;;54229:14;54242:1;54229:10;:14;:::i;:::-;54273:15;;54205:38;;-1:-1:-1;54253:17:0;;54273:19;;54291:1;;54273:19;:::i;:::-;54253:39;;54319:13;54306:9;:26;54302:342;;54348:18;54369:8;54378:9;54369:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;54348:40;;54507:10;54481:8;54490:13;54481:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;:36;;;;;;;;;;;54584:24;;;;;:15;:24;;;;;;:36;;;;;;;;;;;;:49;;;54302:342;54714:8;:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;54794:24;;;;;;:15;:24;;;;;;54714:14;54794:33;;;;;;;;;;;54787:40;;;;54842:31;2881:74:1;;;54794:24:0;54842:31;;2854:18:1;54842:31:0;;;;;;;-1:-1:-1;54890:4:0;;53750:1151;-1:-1:-1;;;;;;53750:1151:0:o;82120:200::-;82268:19;;;;82245:4;82268:19;;;:10;:19;;;;;;;;:27;;;;;;;;;;;:34;;;;;;;;:41;;82245:4;;82268:34;:41;;;:::i;:::-;;;:45;82261:52;;82120:200;;;;;:::o;81767:347::-;33898:40;;;10442:66:1;10537:3;10533:16;;;10529:25;;33898:40:0;;;10517:38:1;10588:16;;;10584:25;10571:11;;;10564:46;10626:11;;;;10619:27;;;33898:40:0;;;;;;;;;;10662:12:1;;;;33898:40:0;;;81894:12;;81937:170;;82059:19;;;;;;;;:10;:19;;;;;;;;:27;;;;;;;;;;;:34;;;;;;81937:170;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:29;:170::i;71234:187::-;71326:6;;;;71342:17;;;;;;;;;;;71374:40;;71326:6;;;71342:17;71326:6;;71374:40;;71307:16;;71374:40;71297:124;71234:187;:::o;67356:808::-;67753:13;;67420:4;;67753:13;;;;;67749:409;;;67807:7;:12;;67818:1;67807:12;:61;;;;-1:-1:-1;67862:4:0;56327:19;:23;67807:61;67782:166;;;;-1:-1:-1;;;67782:166:0;;8577:2:1;67782:166:0;;;8559:21:1;8616:2;8596:18;;;8589:30;8655:34;8635:18;;;8628:62;8726:16;8706:18;;;8699:44;8760:19;;67782:166:0;8375:410:1;67782:166:0;-1:-1:-1;67969:5:0;;67356:808;-1:-1:-1;67356:808:0:o;67749:409::-;68013:12;;:22;;;;:12;;:22;68005:81;;;;-1:-1:-1;;;68005:81:0;;8577:2:1;68005:81:0;;;8559:21:1;8616:2;8596:18;;;8589:30;8655:34;8635:18;;;8628:62;8726:16;8706:18;;;8699:44;8760:19;;68005:81:0;8375:410:1;68005:81:0;-1:-1:-1;68100:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;67356:808:0:o;67749:409::-;67356:808;;;:::o;69813:111::-;66767:13;;;;;;;66759:69;;;;-1:-1:-1;;;66759:69:0;;8992:2:1;66759:69:0;;;8974:21:1;9031:2;9011:18;;;9004:30;9070:34;9050:18;;;9043:62;9141:13;9121:18;;;9114:41;9172:19;;66759:69:0;8790:407:1;66759:69:0;69885:32:::1;69000:10:::0;69885:18:::1;:32::i;49195:474::-:0;49296:16;;49351:19;:12;49296:16;49351;:19::i;:::-;49343:27;-1:-1:-1;32963:2:0;2670:26;16492:2;16488:16;;;16484:28;34217:37;49380:52;;;;-1:-1:-1;;;49380:52:0;;9404:2:1;49380:52:0;;;9386:21:1;9443:2;9423:18;;;9416:30;9482:20;9462:18;;;9455:48;9520:18;;49380:52:0;9202:342:1;49380:52:0;49453:115;49485:23;-1:-1:-1;;49485:21:0;;;:23::i;:::-;49522:36;:28;-1:-1:-1;;49522:26:0;;;:28::i;:::-;-1:-1:-1;;49522:34:0;;:36::i;:::-;49453:18;:115::i;:::-;49442:126;-1:-1:-1;49586:47:0;49597:25;-1:-1:-1;;49597:23:0;;;:25::i;:::-;49624:8;49586:10;:47::i;:::-;49578:84;;;;-1:-1:-1;;;49578:84:0;;9751:2:1;49578:84:0;;;9733:21:1;9790:2;9770:18;;;9763:30;9829:26;9809:18;;;9802:54;9873:18;;49578:84:0;9549:348:1;49578:84:0;49195:474;;;:::o;82326:744::-;82403:4;;82435:25;-1:-1:-1;;82435:23:0;;;:25::i;:::-;82419:41;-1:-1:-1;82470:12:0;82485:24;-1:-1:-1;;82485:22:0;;;:24::i;:::-;82470:39;-1:-1:-1;82519:12:0;82534:23;-1:-1:-1;;82534:21:0;;;:23::i;:::-;82583:19;;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;82519:38;;-1:-1:-1;82583:28:0;;;82575:36;;;;82567:69;;;;-1:-1:-1;;;82567:69:0;;10104:2:1;82567:69:0;;;10086:21:1;10143:2;10123:18;;;10116:30;10182:22;10162:18;;;10155:50;10222:18;;82567:69:0;9902:344:1;82567:69:0;82769:37;82786:6;82794:5;82801:4;82769:16;:37::i;:::-;82765:55;;;82815:5;82808:12;;;;;;;82765:55;82830:19;;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;:36;;;;;;;;;;;;;;82876:18;;;:10;:18;;;;;:27;;;;;;;;;:34;;;82954:36;:28;-1:-1:-1;;82954:26:0;;;:28::i;:36::-;82920:18;;;;;;;;:10;:18;;;;;;;;:25;;;;;;;;;;;:31;;;;;;;;:70;;;;:31;;:70;;;;;;:::i;:::-;-1:-1:-1;83000:24:0;;;;;;;;:16;:24;;;;;;;;:31;;;;;;;;;;;;:42;;;;;;;;;;;;;;;;;;;;82326:744;-1:-1:-1;;;82326:744:0:o;33281:196::-;33400:12;33452:5;33459:10;33435:35;;;;;;;;;:::i;:::-;;;;;;;;;;;;;33428:42;;33281:196;;;;:::o;13655:359::-;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;35074:155::-;35137:7;35163:59;-1:-1:-1;;35163:11:0;;35137:7;32963:2;35137:7;35163:11;:59::i;35312:172::-;35380:7;35406:71;32963:2;35436:37;32963:2;16492;16488:16;;;2670:26;16484:28;35436:37;:::i;:::-;-1:-1:-1;;35406:11:0;;;:71;35475:1;35406:11;:71::i;28308:632::-;28363:16;28391:11;28412:12;28427;28431:7;16492:2;16488:16;2670:26;16484:28;;16246:282;28427:12;28412:27;;;;28549:4;28543:11;28536:18;;28604:3;28597:10;;28650:33;28663:7;28672:3;28678:4;28672:10;28650:12;:33::i;:::-;-1:-1:-1;28807:14:0;;;28823:4;28803:25;28797:4;28790:39;28870:17;;28308:632;;-1:-1:-1;28308:632:0:o;46716:285::-;46826:14;;46873;-1:-1:-1;;46873:12:0;;;:14::i;:::-;46856:31;;46906:36;46935:6;45309:58;;12352:66:1;45309:58:0;;;12340:79:1;12435:12;;;12428:28;;;45179:7:0;;12472:12:1;;45309:58:0;;;;;;;;;;;;45299:69;;;;;;45292:76;;45110:265;;;;46906:36;46897:45;;46961:33;46975:6;46983:10;46961:13;:33::i;34358:143::-;34423:6;34455:38;-1:-1:-1;;34455:15:0;;34423:6;34491:1;34455:15;:38::i;81521:150::-;53366:24;;;81610:4;53366:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;;81633:31;53268:143;34615:136;34679:6;34711:32;-1:-1:-1;;34711:15:0;;32857:1;;34711:15;:32::i;34844:124::-;34907:7;34933:28;-1:-1:-1;;34933:11:0;;32904:1;34958:2;34933:11;:28::i;12796:462::-;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;12065:2;12061:27;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;13212:39;11811:446;17129:399;17268:7;17287:12;17302;17306:7;15386:3;15382:17;2670:26;15378:29;;15059:364;17302:12;17287:27;;;;17398:12;17402:7;17398:3;:12::i;:::-;17391:4;17375:13;17382:6;17375:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17371:77;;;-1:-1:-1;;17426:11:0;;;;;17371:77;17465:13;17472:6;17465:4;:13;:::i;:::-;17458:20;;17495:26;17501:7;17495:26;;17510:4;17516;17495:5;:26::i;:::-;17488:33;17129:399;-1:-1:-1;;;;;;17129:399:0:o;27036:902::-;27114:15;-1:-1:-1;;7972:15:0;;;;27141:69;;;;-1:-1:-1;;;27141:69:0;;11491:2:1;27141:69:0;;;11473:21:1;11530:2;11510:18;;;11503:30;11569:34;11549:18;;;11542:62;11640:10;11620:18;;;11613:38;11668:19;;27141:69:0;11289:404:1;27141:69:0;27228:16;27236:7;27228;:16::i;:::-;27220:72;;;;-1:-1:-1;;;27220:72:0;;11900:2:1;27220:72:0;;;11882:21:1;11939:2;11919:18;;;11912:30;11978:34;11958:18;;;11951:62;12049:13;12029:18;;;12022:41;12080:19;;27220:72:0;11698:407:1;27220:72:0;27302:12;27317;27321:7;16492:2;16488:16;2670:26;16484:28;;16246:282;27317:12;27302:27;;;;27339:15;27357:12;27361:7;15386:3;15382:17;2670:26;15378:29;;15059:364;27357:12;27339:30;;;;27380:11;27501:4;27495:11;27488:18;;27588:7;27583:3;27580:16;27577:94;;;27628:4;27622;27615:18;27577:94;27843:4;27834:7;27828:4;27819:7;27816:1;27809:5;27798:50;27794:55;27879:52;27900:15;27907:7;14417:3;14413:17;;14206:268;27900:15;12061:27;12065:2;12061:27;;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;;11811:446;22455:290;22511:14;22537:12;22552;22556:7;15386:3;15382:17;2670:26;15378:29;;15059:364;22552:12;22537:27;;;;22574:12;22589;22593:7;16492:2;16488:16;2670:26;16484:28;;16246:282;22589:12;22574:27;;22708:21;;;;22455:290;-1:-1:-1;;;22455:290:0:o;41406:227::-;41484:7;41504:17;41523:18;41545:27;41556:4;41562:9;41545:10;:27::i;:::-;41503:69;;;;41582:18;41594:5;41582:11;:18::i;:::-;-1:-1:-1;41617:9:0;41406:227;-1:-1:-1;;;41406:227:0:o;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;-1:-1:-1;;;20263:76:0;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;-1:-1:-1;;;20359:83:0;;13364:2:1;20359:83:0;;;13346:21:1;13403:2;13383:18;;;13376:30;13442:34;13422:18;;;13415:62;13513:28;13493:18;;;13486:56;13559:19;;20359:83:0;13162:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;16702:147::-;16755:7;16820:12;16824:7;16492:2;16488:16;2670:26;16484:28;;16246:282;16820:12;16805;16809:7;15386:3;15382:17;2670:26;15378:29;;15059:364;16805:12;:27;16798:34;;;;16702:147;;;:::o;8645:333::-;8702:8;8726:15;8733:7;14417:3;14413:17;;14206:268;8726:15;:31;;8745:12;8726:31;8722:74;;-1:-1:-1;8780:5:0;;8645:333;-1:-1:-1;8645:333:0:o;8722:74::-;8805:12;8820;8824:7;8820:3;:12::i;:::-;8955:4;8949:11;-1:-1:-1;8936:26:0;;8645:333;-1:-1:-1;;;8645:333:0:o;39341:1279::-;39422:7;39431:12;39652:9;:16;39672:2;39652:22;39648:966;;39941:4;39926:20;;39920:27;39990:4;39975:20;;39969:27;40047:4;40032:20;;40026:27;39690:9;40018:36;40088:25;40099:4;40018:36;39920:27;39969;40088:10;:25::i;:::-;40081:32;;;;;;;;;39648:966;40134:9;:16;40154:2;40134:22;40130:484;;40403:4;40388:20;;40382:27;40453:4;40438:20;;40432:27;40493:23;40504:4;40382:27;40432;40493:10;:23::i;:::-;40486:30;;;;;;;;40130:484;-1:-1:-1;40563:1:0;;-1:-1:-1;40567:35:0;40130:484;39341:1279;;;;;:::o;37646:631::-;37723:20;37714:5;:29;;;;;;;;:::i;:::-;;37710:561;;37646:631;:::o;37710:561::-;37819:29;37810:5;:38;;;;;;;;:::i;:::-;;37806:465;;37864:34;;-1:-1:-1;;;37864:34:0;;13980:2:1;37864:34:0;;;13962:21:1;14019:2;13999:18;;;13992:30;14058:26;14038:18;;;14031:54;14102:18;;37864:34:0;13778:348:1;37806:465:0;37928:35;37919:5;:44;;;;;;;;:::i;:::-;;37915:356;;37979:41;;-1:-1:-1;;;37979:41:0;;14333:2:1;37979:41:0;;;14315:21:1;14372:2;14352:18;;;14345:30;14411:33;14391:18;;;14384:61;14462:18;;37979:41:0;14131:355:1;37915:356:0;38050:30;38041:5;:39;;;;;;;;:::i;:::-;;38037:234;;38096:44;;-1:-1:-1;;;38096:44:0;;14693:2:1;38096:44:0;;;14675:21:1;14732:2;14712:18;;;14705:30;14771:34;14751:18;;;14744:62;14842:4;14822:18;;;14815:32;14864:19;;38096:44:0;14491:398:1;38037:234:0;38170:30;38161:5;:39;;;;;;;;:::i;:::-;;38157:114;;38216:44;;-1:-1:-1;;;38216:44:0;;15096:2:1;38216:44:0;;;15078:21:1;15135:2;15115:18;;;15108:30;15174:34;15154:18;;;15147:62;15245:4;15225:18;;;15218:32;15267:19;;38216:44:0;14894:398:1;18761:741:0;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19061:33;;;19244:1;19306;19386;19448;19130:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19104:391;;18926:576;;;;18761:741;;;;;;:::o;42814:1603::-;42940:7;;43864:66;43851:79;;43847:161;;;-1:-1:-1;43962:1:0;;-1:-1:-1;43966:30:0;43946:51;;43847:161;44021:1;:7;;44026:2;44021:7;;:18;;;;;44032:1;:7;;44037:2;44032:7;;44021:18;44017:100;;;-1:-1:-1;44071:1:0;;-1:-1:-1;44075:30:0;44055:51;;44017:100;44228:24;;;44211:14;44228:24;;;;;;;;;17039:25:1;;;17112:4;17100:17;;17080:18;;;17073:45;;;;17134:18;;;17127:34;;;17177:18;;;17170:34;;;44228:24:0;;17011:19:1;;44228:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44228:24:0;;;;;;-1:-1:-1;;44266:20:0;;;44262:101;;44318:1;44322:29;44302:50;;;;;;;44262:101;44381:6;-1:-1:-1;44389:20:0;;-1:-1:-1;42814:1603:0;;;;;;;;:::o;41887:336::-;41997:7;;42055:66;42042:80;;41997:7;42148:25;42164:3;42149:18;;;42171:2;42148:25;:::i;:::-;42132:42;;42191:25;42202:4;42208:1;42211;42214;42191:10;:25::i;:::-;42184:32;;;;;;41887:336;;;;;;:::o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;2943:1393::-;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4268:57::-;3007:1329;2943:1393;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:163:1;81:20;;141:10;130:22;;120:33;;110:61;;167:1;164;157:12;182:256;248:6;256;309:2;297:9;288:7;284:23;280:32;277:52;;;325:1;322;315:12;277:52;348:28;366:9;348:28;:::i;:::-;338:38;;395:37;428:2;417:9;413:18;395:37;:::i;:::-;385:47;;182:256;;;;;:::o;625:324::-;700:6;708;716;769:2;757:9;748:7;744:23;740:32;737:52;;;785:1;782;775:12;737:52;808:28;826:9;808:28;:::i;:::-;798:38;;855:37;888:2;877:9;873:18;855:37;:::i;:::-;845:47;;939:2;928:9;924:18;911:32;901:42;;625:324;;;;;:::o;1136:196::-;1204:20;;1264:42;1253:54;;1243:65;;1233:93;;1322:1;1319;1312:12;1337:258;1404:6;1412;1465:2;1453:9;1444:7;1440:23;1436:32;1433:52;;;1481:1;1478;1471:12;1433:52;1504:28;1522:9;1504:28;:::i;:::-;1494:38;;1551;1585:2;1574:9;1570:18;1551:38;:::i;1929:258::-;2001:1;2011:113;2025:6;2022:1;2019:13;2011:113;;;2101:11;;;2095:18;2082:11;;;2075:39;2047:2;2040:10;2011:113;;;2142:6;2139:1;2136:13;2133:48;;;2177:1;2168:6;2163:3;2159:16;2152:27;2133:48;;1929:258;;;:::o;2192:316::-;2233:3;2271:5;2265:12;2298:6;2293:3;2286:19;2314:63;2370:6;2363:4;2358:3;2354:14;2347:4;2340:5;2336:16;2314:63;:::i;:::-;2422:2;2410:15;2427:66;2406:88;2397:98;;;;2497:4;2393:109;;2192:316;-1:-1:-1;;2192:316:1:o;2513:217::-;2660:2;2649:9;2642:21;2623:4;2680:44;2720:2;2709:9;2705:18;2697:6;2680:44;:::i;2966:184::-;3024:6;3077:2;3065:9;3056:7;3052:23;3048:32;3045:52;;;3093:1;3090;3083:12;3045:52;3116:28;3134:9;3116:28;:::i;3352:186::-;3411:6;3464:2;3452:9;3443:7;3439:23;3435:32;3432:52;;;3480:1;3477;3470:12;3432:52;3503:29;3522:9;3503:29;:::i;3543:184::-;3595:77;3592:1;3585:88;3692:4;3689:1;3682:15;3716:4;3713:1;3706:15;3732:980;3800:6;3853:2;3841:9;3832:7;3828:23;3824:32;3821:52;;;3869:1;3866;3859:12;3821:52;3909:9;3896:23;3938:18;3979:2;3971:6;3968:14;3965:34;;;3995:1;3992;3985:12;3965:34;4033:6;4022:9;4018:22;4008:32;;4078:7;4071:4;4067:2;4063:13;4059:27;4049:55;;4100:1;4097;4090:12;4049:55;4136:2;4123:16;4158:2;4154;4151:10;4148:36;;;4164:18;;:::i;:::-;4298:2;4292:9;4360:4;4352:13;;4203:66;4348:22;;;4372:2;4344:31;4340:40;4328:53;;;4396:18;;;4416:22;;;4393:46;4390:72;;;4442:18;;:::i;:::-;4482:10;4478:2;4471:22;4517:2;4509:6;4502:18;4557:7;4552:2;4547;4543;4539:11;4535:20;4532:33;4529:53;;;4578:1;4575;4568:12;4529:53;4634:2;4629;4625;4621:11;4616:2;4608:6;4604:15;4591:46;4679:1;4657:15;;;4674:2;4653:24;4646:35;;;;-1:-1:-1;4661:6:1;3732:980;-1:-1:-1;;;;;3732:980:1:o;5243:184::-;5295:77;5292:1;5285:88;5392:4;5389:1;5382:15;5416:4;5413:1;5406:15;7425:184;7477:77;7474:1;7467:88;7574:4;7571:1;7564:15;7598:4;7595:1;7588:15;7614:125;7654:4;7682:1;7679;7676:8;7673:34;;;7687:18;;:::i;:::-;-1:-1:-1;7724:9:1;;7614:125::o;7744:184::-;7796:77;7793:1;7786:88;7893:4;7890:1;7883:15;7917:4;7914:1;7907:15;7933:437;8012:1;8008:12;;;;8055;;;8076:61;;8130:4;8122:6;8118:17;8108:27;;8076:61;8183:2;8175:6;8172:14;8152:18;8149:38;8146:218;;8220:77;8217:1;8210:88;8321:4;8318:1;8311:15;8349:4;8346:1;8339:15;10685:466;10860:3;10898:6;10892:13;10914:53;10960:6;10955:3;10948:4;10940:6;10936:17;10914:53;:::i;:::-;11030:13;;10989:16;;;;11052:57;11030:13;10989:16;11086:4;11074:17;;11052:57;:::i;:::-;11125:20;;10685:466;-1:-1:-1;;;;10685:466:1:o;11156:128::-;11196:3;11227:1;11223:6;11220:1;11217:13;11214:39;;;11233:18;;:::i;:::-;-1:-1:-1;11269:9:1;;11156:128::o;12495:195::-;12533:4;12570;12567:1;12563:12;12602:4;12599:1;12595:12;12627:3;12622;12619:12;12616:38;;;12634:18;;:::i;:::-;12671:13;;;12495:195;-1:-1:-1;;;12495:195:1:o;12695:238::-;12733:7;12773:4;12770:1;12766:12;12805:4;12802:1;12798:12;12865:3;12859:4;12855:14;12850:3;12847:23;12840:3;12833:11;12826:19;12822:49;12819:75;;;12874:18;;:::i;:::-;12914:13;;12695:238;-1:-1:-1;;;12695:238:1:o;13589:184::-;13641:77;13638:1;13631:88;13738:4;13735:1;13728:15;13762:4;13759:1;13752:15;15416:1391;16138:34;16126:47;;16203:23;16198:2;16189:12;;16182:45;16246:66;16350:3;16346:16;;;16342:25;;16337:2;16328:12;;16321:47;16387:17;16429:2;16420:12;;16413:24;;;16471:16;;;16467:25;;16462:2;16453:12;;16446:47;16523:34;16518:2;16509:12;;16502:56;16589:3;16583;16574:13;;16567:26;16628:16;;;16624:25;;16618:3;16609:13;;16602:48;16675:3;16666:13;;16659:25;16719:16;;;16715:25;16709:3;16700:13;;16693:48;15374:3;16796;16787:13;;15362:16;-1:-1:-1;15394:11:1;;;16757:44;15297:114","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"AttestationSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_notary","type":"address"}],"name":"addNotary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"getAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_notary","type":"address"}],"name":"getLatestAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"}],"name":"getLatestAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"address","name":"","type":"address"}],"name":"latestNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"address","name":"","type":"address"}],"name":"latestRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_notary","type":"address"}],"name":"removeNotary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"}],"name":"rootsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"submitAttestation","outputs":[{"internalType":"bool","name":"attestationStored","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"getAttestation(uint32,uint32,bytes32)":{"notice":"Get attestation for (domain, nonce, root), if exists."},"getAttestation(uint32,uint32,uint256)":{"notice":"Get i-th attestation for given (domain, nonce), if exists. Assuming no fraud is committed, index = 0 should be used. If fraud was committed, there might be more than one attestation for given (domain, nonce)."},"getLatestAttestation(uint32)":{"notice":"Get latest attestation for the domain."},"getLatestAttestation(uint32,address)":{"notice":"Get latest attestation for the domain signed by given Notary."},"getRoot(uint32,uint32,uint256)":{"notice":"Get i-th root for given (domain, nonce), if exists. Assuming no fraud is committed, index = 0 should be used. If fraud was committed, there might be more than one root for given (domain, nonce)."},"rootsAmount(uint32,uint32)":{"notice":"Get amount of attested roots for given (domain, nonce). Assuming no fraud is committed, amount \u003c= 1. If amount \u003e 1, fraud was committed."}},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"attestationRoots":{"details":"All submitted Notary Attestations are stored. As different Notaries might sign attestations with the same nonce, but different root (meaning one of the attestations is fraudulent), we need a system so store all such attestations. `attestationRoots` stores a list of attested roots for every (domain, nonce) pair `signatures` stores a signature for every submitted (domain, nonce, root) attestation. We only store the first submitted signature for such attestation."},"latestNonce":{"details":"We are also storing last submitted (nonce, root) attestation for every Notary."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"AttestationSubmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"addNotary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"getAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"getLatestAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"}],\"name\":\"getLatestAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"latestNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"latestRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"removeNotary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"}],\"name\":\"rootsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"attestationStored\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"attestationRoots\":{\"details\":\"All submitted Notary Attestations are stored. As different Notaries might sign attestations with the same nonce, but different root (meaning one of the attestations is fraudulent), we need a system so store all such attestations. `attestationRoots` stores a list of attested roots for every (domain, nonce) pair `signatures` stores a signature for every submitted (domain, nonce, root) attestation. We only store the first submitted signature for such attestation.\"},\"latestNonce\":{\"details\":\"We are also storing last submitted (nonce, root) attestation for every Notary.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAttestation(uint32,uint32,bytes32)\":{\"notice\":\"Get attestation for (domain, nonce, root), if exists.\"},\"getAttestation(uint32,uint32,uint256)\":{\"notice\":\"Get i-th attestation for given (domain, nonce), if exists. Assuming no fraud is committed, index = 0 should be used. If fraud was committed, there might be more than one attestation for given (domain, nonce).\"},\"getLatestAttestation(uint32)\":{\"notice\":\"Get latest attestation for the domain.\"},\"getLatestAttestation(uint32,address)\":{\"notice\":\"Get latest attestation for the domain signed by given Notary.\"},\"getRoot(uint32,uint32,uint256)\":{\"notice\":\"Get i-th root for given (domain, nonce), if exists. Assuming no fraud is committed, index = 0 should be used. If fraud was committed, there might be more than one root for given (domain, nonce).\"},\"rootsAmount(uint32,uint32)\":{\"notice\":\"Get amount of attested roots for given (domain, nonce). Assuming no fraud is committed, amount \u003c= 1. If amount \u003e 1, fraud was committed.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"AttestationCollector\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{"addNotary(uint32,address)":"2af678b0","getAttestation(uint32,uint32,bytes32)":"563ffbec","getAttestation(uint32,uint32,uint256)":"bb07a791","getLatestAttestation(uint32)":"a7d729bd","getLatestAttestation(uint32,address)":"7eb2923f","getRoot(uint32,uint32,uint256)":"289def8d","initialize()":"8129fc1c","latestNonce(uint32,address)":"d53f2eec","latestRoot(uint32,address)":"d4516803","owner()":"8da5cb5b","removeNotary(uint32,address)":"4b82bad7","renounceOwnership()":"715018a6","rootsAmount(uint32,uint32)":"17007970","submitAttestation(bytes)":"f646a512","transferOwnership(address)":"f2fde38b"}},"solidity/AttestationCollector.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201424546045ea27bec3e25d3f0ff3c80b4568503c646b3ee3fa51a36a155ce67f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212201424546045ea27bec3e25d3f0ff3c80b4568503c646b3ee3fa51a36a155ce67f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"46393:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;46393:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"46393:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:AuthManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"AuthManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e9653e8e5505d59889cb00d1307a68b4424be601af807311fbda8f71a299512764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e9653e8e5505d59889cb00d1307a68b4424be601af807311fbda8f71a299512764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"37467:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;37467:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"37467:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"custom:oz-upgrades-unsafe-allow":"constructor constructor() { _disableInitializers(); } ``` ====","details":"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\"MyToken\", \"MTK\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\"MyToken\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```","events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor constructor() { _disableInitializers(); } ``` ====\",\"details\":\"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\\\"MyToken\\\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:NotaryRegistry":{"code":"0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220a3a24aa9797da5ab584e8a150e23f1ff4388cf90cf9573a4719eb0ac78e37fad64736f6c634300080d0033","runtime-code":"0x6080604052600080fdfea2646970667358221220a3a24aa9797da5ab584e8a150e23f1ff4388cf90cf9573a4719eb0ac78e37fad64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"50643:4260:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"50643:4260:0:-:0;;;;;","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"NotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/AttestationCollector.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204b3b65680f5c760942b2153fb8c40b355f26a840c28b6079f9365abda9d4985b64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204b3b65680f5c760942b2153fb8c40b355f26a840c28b6079f9365abda9d4985b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"35580:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;35580:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"35580:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220506cedf33a125f7290e6fd62dcbafe680f2917ad85961fec39783b466cb7807864736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220506cedf33a125f7290e6fd62dcbafe680f2917ad85961fec39783b466cb7807864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract NotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]] (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isNotary(uint32 _domain, address _notary) internal view returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1), we swap the Notary to delete with the last one in\n // the array, and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is AuthManager, NotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkUpdaterAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _notary) internal view override returns (bool) {\n return _isNotary(_homeDomain, _notary);\n }\n\n function _isWatchtower(address _watchtower) internal view override returns (bool) {}\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x50bcdaeeb6713f85d43eccf9c38a96b1364d61cec771bfdcd69659d601c67be8\",\"urls\":[\"bzz-raw://1e1a7cecbb4ead64de3f086520714d589447fdc27eb57b1571db8dc7271c373f\",\"dweb:/ipfs/QmW8EKZt55r7GtdW2kPv5jg3JktqGw9djxBoLgjo6CHLBY\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}}} \ No newline at end of file +{"solidity/AttestationCollector.sol:AbstractNotaryRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"AbstractNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220805edcea6ad8f670347550cddf18353b53fb4e3924b563093c0d20a8ecd780f564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220805edcea6ad8f670347550cddf18353b53fb4e3924b563093c0d20a8ecd780f564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"52638:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;52638:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"52638:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205fdc42d61385a9fedec2650f0f5625d6cd35f51e97fa6fd2ec166a54aacff00564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205fdc42d61385a9fedec2650f0f5625d6cd35f51e97fa6fd2ec166a54aacff00564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32270:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32270:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32270:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:AttestationCollector":{"code":"0x608060405234801561001057600080fd5b506127d8806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638129fc1c11610097578063d451680311610066578063d4516803146101ec578063d53f2eec14610217578063f2fde38b1461025d578063f646a5121461027057600080fd5b80638129fc1c146101965780638da5cb5b1461019e578063a7d729bd146101c6578063bb07a791146101d957600080fd5b80634b82bad7116100d35780634b82bad714610148578063563ffbec1461015b578063715018a61461017b5780637eb2923f1461018357600080fd5b806317007970146100fa578063289def8d146101205780632af678b014610133575b600080fd5b61010d610108366004612234565b610293565b6040519081526020015b60405180910390f35b61010d61012e366004612267565b6102bd565b6101466101413660046122c7565b61037e565b005b6101466101563660046122c7565b6103f4565b61016e610169366004612267565b610465565b604051610117919061236b565b6101466104d1565b61016e6101913660046122c7565b610544565b61014661061b565b60655460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b61016e6101d436600461237e565b6106ca565b61016e6101e7366004612267565b610865565b61010d6101fa3660046122c7565b609a60209081526000928352604080842090915290825290205481565b6102486102253660046122c7565b609960209081526000928352604080842090915290825290205463ffffffff1681565b60405163ffffffff9091168152602001610117565b61014661026b366004612399565b610881565b61028361027e3660046123e3565b61097a565b6040519015158152602001610117565b63ffffffff8083166000908152609760209081526040808320938516835292905220545b92915050565b63ffffffff808416600090815260976020908152604080832093861683529290529081205482106103355760405162461bcd60e51b815260206004820152600660248201527f21696e646578000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b63ffffffff8085166000908152609760209081526040808320938716835292905220805483908110610369576103696124b2565b906000526020600020015490505b9392505050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146103e55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef82826109f4565b505050565b60655473ffffffffffffffffffffffffffffffffffffffff16331461045b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef8282610af1565b6060610472848484610d1a565b6104be5760405162461bcd60e51b815260206004820152600a60248201527f217369676e617475726500000000000000000000000000000000000000000000604482015260640161032c565b6104c9848484610d60565b949350505050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146105385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6105426000610e73565b565b63ffffffff808316600090815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205460609216908190036105d05760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b63ffffffff84166000908152609a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610612858383610d60565b95945050505050565b60006106276001610eea565b9050801561065c57603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610664611043565b80156106c757603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b63ffffffff81166000908152602081905260408120546060918190036107325760405162461bcd60e51b815260206004820152600960248201527f216e6f7461726965730000000000000000000000000000000000000000000000604482015260640161032c565b600080805b838110156108035763ffffffff86166000908152602081905260408120805483908110610766576107666124b2565b600091825260208083209091015463ffffffff808b16845260998352604080852073ffffffffffffffffffffffffffffffffffffffff9093168086529290935291909220549192509081169085168111156107f95763ffffffff88166000908152609a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020549094509250835b5050600101610737565b508163ffffffff1660000361085a5760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b610612858383610d60565b606060006108748585856102bd565b9050610612858583610d60565b60655473ffffffffffffffffffffffffffffffffffffffff1633146108e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b73ffffffffffffffffffffffffffffffffffffffff81166109715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161032c565b6106c781610e73565b6000806000610988846110c9565b91509150610996828261120e565b925082156109ed578173ffffffffffffffffffffffffffffffffffffffff167f786431104fc3c4b19da7bae78f422f46b9c07528276a2ee430e8569cb8705f14856040516109e4919061236b565b60405180910390a25b5050919050565b63ffffffff8216600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415610a38575060006102b7565b63ffffffff831660008181526020818152604080832080546001808201835582865284862090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16908117909155868652915490845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b63ffffffff8216600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054808203610b395760009150506102b7565b63ffffffff8416600090815260208190526040812090610b5a600184612510565b8254909150600090610b6e90600190612510565b9050818114610c3a576000838281548110610b8b57610b8b6124b2565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080848481548110610bcb57610bcb6124b2565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94851617905563ffffffff8b1682526001815260408083209490931682529290925290208490555b82805480610c4a57610c4a612527565b600082815260208082207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908401810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925563ffffffff891680835260018252604080842073ffffffffffffffffffffffffffffffffffffffff8b168086529084528185209490945551928352917f3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b910160405180910390a25060019695505050505050565b63ffffffff8084166000908152609860209081526040808320938616835292815282822084835290529081208054829190610d5490612556565b90501190509392505050565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086811b8216602084015285901b16602482015260288082018490528251808303909101815260489091019091526060906104c99063ffffffff808716600090815260986020908152604080832093891683529281528282208783529052208054610df090612556565b80601f0160208091040260200160405190810160405280929190818152602001828054610e1c90612556565b8015610e695780601f10610e3e57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610e4c57829003601f168201915b50505050506113fe565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b603254600090610100900460ff1615610f89578160ff166001148015610f0f5750303b155b610f815760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b506000919050565b60325460ff8084169116106110065760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b50603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b603254610100900460ff166110c05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161032c565b61054233610e73565b6000806110d6838261142a565b905060286bffffffffffffffffffffffff601883901c161161113a5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161032c565b61116e61114c62ffffff198316611445565b61116961115e62ffffff19851661145a565b62ffffff191661148d565b6114e0565b91506111bd61118262ffffff198316611557565b63ffffffff16600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6112095760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161032c565b915091565b60008061122062ffffff198416611557565b9050600061123362ffffff19851661156b565b9050600061124662ffffff19861661157f565b63ffffffff808516600090815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c168452909152902054919250908116908316116112d45760405162461bcd60e51b815260206004820152601460248201527f4f75746461746564206174746573746174696f6e000000000000000000000000604482015260640161032c565b6112df838383610d1a565b156112f057600093505050506102b7565b63ffffffff838116600081815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001696891696909617909555928252609a815282822093825292909252902081905561137f61115e62ffffff19871661145a565b63ffffffff80851660009081526098602090815260408083209387168352928152828220858352815291902082516113bd9391929190910190612187565b5063ffffffff928316600090815260976020908152604080832094909516825292835292832080546001808201835591855292909320909101559392505050565b606082826040516020016114139291906125a3565b604051602081830303815290604052905092915050565b81516000906020840161061264ffffffffff85168284611594565b60006102b762ffffff198316826028816115d9565b60006102b7602861147d81601886901c6bffffffffffffffffffffffff16612510565b62ffffff198516919060006115d9565b60606000806114aa8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506114cf848360200161165d565b508181016020016040529052919050565b6000806114f262ffffff1985166117f8565b905061154b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506104c98184611855565b60006102b762ffffff198316826004611879565b60006102b762ffffff198316600480611879565b60006102b762ffffff198316600860206118a9565b6000806115a183856125d2565b90506040518111156115b1575060005b806000036115c65762ffffff19915050610377565b606085811b8517901b831760181b610612565b6000806115f48660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061160d86611a67565b8461161887846125d2565b61162291906125d2565b11156116355762ffffff199150506104c9565b61163f85826125d2565b90506116538364ffffffffff168286611594565b9695505050505050565b600062ffffff19808416036116da5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161032c565b6116e383611aaf565b6117555760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161032c565b600061176f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006117998560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156117be5760206060fd5b8285848460045afa506116536117d48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806118138360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061183d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006118648585611aec565b9150915061187181611b5a565b509392505050565b60006118868260206125ea565b61189190600861260d565b60ff1661189f8585856118a9565b901c949350505050565b60008160ff166000036118be57506000610377565b6118d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118f160ff8416856125d2565b1115611969576119506119128560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119388660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16611d46565b60405162461bcd60e51b815260040161032c919061236b565b60208260ff1611156119e35760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161032c565b600882026000611a018660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000611a818260181c6bffffffffffffffffffffffff1690565b611a998360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000611abb8260d81c90565b64ffffffffff1664ffffffffff03611ad557506000919050565b6000611ae083611a67565b60405110199392505050565b6000808251604103611b225760208301516040840151606085015160001a611b1687828585611db4565b94509450505050611b53565b8251604003611b4b5760208301516040840151611b40868383611ecc565b935093505050611b53565b506000905060025b9250929050565b6000816004811115611b6e57611b6e612636565b03611b765750565b6001816004811115611b8a57611b8a612636565b03611bd75760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161032c565b6002816004811115611beb57611beb612636565b03611c385760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161032c565b6003816004811115611c4c57611c4c612636565b03611cbf5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b6004816004811115611cd357611cd3612636565b036106c75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b60606000611d5386611f1e565b9150506000611d6186611f1e565b9150506000611d6f86611f1e565b9150506000611d7d86611f1e565b91505083838383604051602001611d979493929190612665565b604051602081830303815290604052945050505050949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611deb5750600090506003611ec3565b8460ff16601b14158015611e0357508460ff16601c14155b15611e145750600090506004611ec3565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e68573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611ebc57600060019250925050611ec3565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681611f0260ff86901c601b6125d2565b9050611f1087828885611db4565b935093505050935093915050565b600080601f5b600f8160ff161115611f91576000611f3d82600861260d565b60ff1685901c9050611f4e81612008565b61ffff16841793508160ff16601014611f6957601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f24565b50600f5b60ff8160ff161015612002576000611fae82600861260d565b60ff1685901c9050611fbf81612008565b61ffff16831792508160ff16600014611fda57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f95565b50915091565b600061201a60048360ff16901c61203a565b60ff1661ffff919091161760081b6120318261203a565b60ff1617919050565b600060f08083179060ff821690036120555750603092915050565b8060ff1660f1036120695750603192915050565b8060ff1660f20361207d5750603292915050565b8060ff1660f3036120915750603392915050565b8060ff1660f4036120a55750603492915050565b8060ff1660f5036120b95750603592915050565b8060ff1660f6036120cd5750603692915050565b8060ff1660f7036120e15750603792915050565b8060ff1660f8036120f55750603892915050565b8060ff1660f9036121095750603992915050565b8060ff1660fa0361211d5750606192915050565b8060ff1660fb036121315750606292915050565b8060ff1660fc036121455750606392915050565b8060ff1660fd036121595750606492915050565b8060ff1660fe0361216d5750606592915050565b8060ff1660ff036121815750606692915050565b50919050565b82805461219390612556565b90600052602060002090601f0160209004810192826121b557600085556121fb565b82601f106121ce57805160ff19168380011785556121fb565b828001600101855582156121fb579182015b828111156121fb5782518255916020019190600101906121e0565b5061220792915061220b565b5090565b5b80821115612207576000815560010161220c565b803563ffffffff8116811461103e57600080fd5b6000806040838503121561224757600080fd5b61225083612220565b915061225e60208401612220565b90509250929050565b60008060006060848603121561227c57600080fd5b61228584612220565b925061229360208501612220565b9150604084013590509250925092565b803573ffffffffffffffffffffffffffffffffffffffff8116811461103e57600080fd5b600080604083850312156122da57600080fd5b6122e383612220565b915061225e602084016122a3565b60005b8381101561230c5781810151838201526020016122f4565b8381111561231b576000848401525b50505050565b600081518084526123398160208601602086016122f1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006103776020830184612321565b60006020828403121561239057600080fd5b61037782612220565b6000602082840312156123ab57600080fd5b610377826122a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156123f557600080fd5b813567ffffffffffffffff8082111561240d57600080fd5b818401915084601f83011261242157600080fd5b813581811115612433576124336123b4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612479576124796123b4565b8160405282815287602084870101111561249257600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612522576125226124e1565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600181811c9082168061256a57607f821691505b602082108103612181577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600083516125b58184602088016122f1565b8351908301906125c98183602088016122f1565b01949350505050565b600082198211156125e5576125e56124e1565b500190565b600060ff821660ff841680821015612604576126046124e1565b90039392505050565b600060ff821660ff84168160ff048111821515161561262e5761262e6124e1565b029392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161165356fea2646970667358221220282727d67bb627ed57f2f72ef2060c7fa79561d82a651fdd63c80edd00ecd8fe64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80638129fc1c11610097578063d451680311610066578063d4516803146101ec578063d53f2eec14610217578063f2fde38b1461025d578063f646a5121461027057600080fd5b80638129fc1c146101965780638da5cb5b1461019e578063a7d729bd146101c6578063bb07a791146101d957600080fd5b80634b82bad7116100d35780634b82bad714610148578063563ffbec1461015b578063715018a61461017b5780637eb2923f1461018357600080fd5b806317007970146100fa578063289def8d146101205780632af678b014610133575b600080fd5b61010d610108366004612234565b610293565b6040519081526020015b60405180910390f35b61010d61012e366004612267565b6102bd565b6101466101413660046122c7565b61037e565b005b6101466101563660046122c7565b6103f4565b61016e610169366004612267565b610465565b604051610117919061236b565b6101466104d1565b61016e6101913660046122c7565b610544565b61014661061b565b60655460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610117565b61016e6101d436600461237e565b6106ca565b61016e6101e7366004612267565b610865565b61010d6101fa3660046122c7565b609a60209081526000928352604080842090915290825290205481565b6102486102253660046122c7565b609960209081526000928352604080842090915290825290205463ffffffff1681565b60405163ffffffff9091168152602001610117565b61014661026b366004612399565b610881565b61028361027e3660046123e3565b61097a565b6040519015158152602001610117565b63ffffffff8083166000908152609760209081526040808320938516835292905220545b92915050565b63ffffffff808416600090815260976020908152604080832093861683529290529081205482106103355760405162461bcd60e51b815260206004820152600660248201527f21696e646578000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b63ffffffff8085166000908152609760209081526040808320938716835292905220805483908110610369576103696124b2565b906000526020600020015490505b9392505050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146103e55760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef82826109f4565b505050565b60655473ffffffffffffffffffffffffffffffffffffffff16331461045b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6103ef8282610af1565b6060610472848484610d1a565b6104be5760405162461bcd60e51b815260206004820152600a60248201527f217369676e617475726500000000000000000000000000000000000000000000604482015260640161032c565b6104c9848484610d60565b949350505050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146105385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b6105426000610e73565b565b63ffffffff808316600090815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205460609216908190036105d05760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b63ffffffff84166000908152609a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054610612858383610d60565b95945050505050565b60006106276001610eea565b9050801561065c57603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610664611043565b80156106c757603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50565b63ffffffff81166000908152602081905260408120546060918190036107325760405162461bcd60e51b815260206004820152600960248201527f216e6f7461726965730000000000000000000000000000000000000000000000604482015260640161032c565b600080805b838110156108035763ffffffff86166000908152602081905260408120805483908110610766576107666124b2565b600091825260208083209091015463ffffffff808b16845260998352604080852073ffffffffffffffffffffffffffffffffffffffff9093168086529290935291909220549192509081169085168111156107f95763ffffffff88166000908152609a6020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091529020549094509250835b5050600101610737565b508163ffffffff1660000361085a5760405162461bcd60e51b815260206004820152601560248201527f4e6f206174746573746174696f6e7320666f756e640000000000000000000000604482015260640161032c565b610612858383610d60565b606060006108748585856102bd565b9050610612858583610d60565b60655473ffffffffffffffffffffffffffffffffffffffff1633146108e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161032c565b73ffffffffffffffffffffffffffffffffffffffff81166109715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161032c565b6106c781610e73565b6000806000610988846110c9565b91509150610996828261120e565b925082156109ed578173ffffffffffffffffffffffffffffffffffffffff167f786431104fc3c4b19da7bae78f422f46b9c07528276a2ee430e8569cb8705f14856040516109e4919061236b565b60405180910390a25b5050919050565b63ffffffff8216600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415610a38575060006102b7565b63ffffffff831660008181526020818152604080832080546001808201835582865284862090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a16908117909155868652915490845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b63ffffffff8216600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054808203610b395760009150506102b7565b63ffffffff8416600090815260208190526040812090610b5a600184612510565b8254909150600090610b6e90600190612510565b9050818114610c3a576000838281548110610b8b57610b8b6124b2565b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080848481548110610bcb57610bcb6124b2565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94851617905563ffffffff8b1682526001815260408083209490931682529290925290208490555b82805480610c4a57610c4a612527565b600082815260208082207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908401810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590920190925563ffffffff891680835260018252604080842073ffffffffffffffffffffffffffffffffffffffff8b168086529084528185209490945551928352917f3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b910160405180910390a25060019695505050505050565b63ffffffff8084166000908152609860209081526040808320938616835292815282822084835290529081208054829190610d5490612556565b90501190509392505050565b604080517fffffffff0000000000000000000000000000000000000000000000000000000060e086811b8216602084015285901b16602482015260288082018490528251808303909101815260489091019091526060906104c99063ffffffff808716600090815260986020908152604080832093891683529281528282208783529052208054610df090612556565b80601f0160208091040260200160405190810160405280929190818152602001828054610e1c90612556565b8015610e695780601f10610e3e57610100808354040283529160200191610e69565b820191906000526020600020905b815481529060010190602001808311610e4c57829003601f168201915b50505050506113fe565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b603254600090610100900460ff1615610f89578160ff166001148015610f0f5750303b155b610f815760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b506000919050565b60325460ff8084169116106110065760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161032c565b50603280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b603254610100900460ff166110c05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161032c565b61054233610e73565b6000806110d6838261142a565b905060286bffffffffffffffffffffffff601883901c161161113a5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161032c565b61116e61114c62ffffff198316611445565b61116961115e62ffffff19851661145a565b62ffffff191661148d565b6114e0565b91506111bd61118262ffffff198316611557565b63ffffffff16600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6112095760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161032c565b915091565b60008061122062ffffff198416611557565b9050600061123362ffffff19851661156b565b9050600061124662ffffff19861661157f565b63ffffffff808516600090815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c168452909152902054919250908116908316116112d45760405162461bcd60e51b815260206004820152601460248201527f4f75746461746564206174746573746174696f6e000000000000000000000000604482015260640161032c565b6112df838383610d1a565b156112f057600093505050506102b7565b63ffffffff838116600081815260996020908152604080832073ffffffffffffffffffffffffffffffffffffffff8c1680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001696891696909617909555928252609a815282822093825292909252902081905561137f61115e62ffffff19871661145a565b63ffffffff80851660009081526098602090815260408083209387168352928152828220858352815291902082516113bd9391929190910190612187565b5063ffffffff928316600090815260976020908152604080832094909516825292835292832080546001808201835591855292909320909101559392505050565b606082826040516020016114139291906125a3565b604051602081830303815290604052905092915050565b81516000906020840161061264ffffffffff85168284611594565b60006102b762ffffff198316826028816115d9565b60006102b7602861147d81601886901c6bffffffffffffffffffffffff16612510565b62ffffff198516919060006115d9565b60606000806114aa8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506114cf848360200161165d565b508181016020016040529052919050565b6000806114f262ffffff1985166117f8565b905061154b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506104c98184611855565b60006102b762ffffff198316826004611879565b60006102b762ffffff198316600480611879565b60006102b762ffffff198316600860206118a9565b6000806115a183856125d2565b90506040518111156115b1575060005b806000036115c65762ffffff19915050610377565b606085811b8517901b831760181b610612565b6000806115f48660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061160d86611a67565b8461161887846125d2565b61162291906125d2565b11156116355762ffffff199150506104c9565b61163f85826125d2565b90506116538364ffffffffff168286611594565b9695505050505050565b600062ffffff19808416036116da5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161032c565b6116e383611aaf565b6117555760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161032c565b600061176f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006117998560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156117be5760206060fd5b8285848460045afa506116536117d48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806118138360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061183d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006118648585611aec565b9150915061187181611b5a565b509392505050565b60006118868260206125ea565b61189190600861260d565b60ff1661189f8585856118a9565b901c949350505050565b60008160ff166000036118be57506000610377565b6118d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118f160ff8416856125d2565b1115611969576119506119128560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119388660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16611d46565b60405162461bcd60e51b815260040161032c919061236b565b60208260ff1611156119e35760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161032c565b600882026000611a018660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000611a818260181c6bffffffffffffffffffffffff1690565b611a998360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000611abb8260d81c90565b64ffffffffff1664ffffffffff03611ad557506000919050565b6000611ae083611a67565b60405110199392505050565b6000808251604103611b225760208301516040840151606085015160001a611b1687828585611db4565b94509450505050611b53565b8251604003611b4b5760208301516040840151611b40868383611ecc565b935093505050611b53565b506000905060025b9250929050565b6000816004811115611b6e57611b6e612636565b03611b765750565b6001816004811115611b8a57611b8a612636565b03611bd75760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161032c565b6002816004811115611beb57611beb612636565b03611c385760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161032c565b6003816004811115611c4c57611c4c612636565b03611cbf5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b6004816004811115611cd357611cd3612636565b036106c75760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161032c565b60606000611d5386611f1e565b9150506000611d6186611f1e565b9150506000611d6f86611f1e565b9150506000611d7d86611f1e565b91505083838383604051602001611d979493929190612665565b604051602081830303815290604052945050505050949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611deb5750600090506003611ec3565b8460ff16601b14158015611e0357508460ff16601c14155b15611e145750600090506004611ec3565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611e68573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611ebc57600060019250925050611ec3565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681611f0260ff86901c601b6125d2565b9050611f1087828885611db4565b935093505050935093915050565b600080601f5b600f8160ff161115611f91576000611f3d82600861260d565b60ff1685901c9050611f4e81612008565b61ffff16841793508160ff16601014611f6957601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f24565b50600f5b60ff8160ff161015612002576000611fae82600861260d565b60ff1685901c9050611fbf81612008565b61ffff16831792508160ff16600014611fda57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611f95565b50915091565b600061201a60048360ff16901c61203a565b60ff1661ffff919091161760081b6120318261203a565b60ff1617919050565b600060f08083179060ff821690036120555750603092915050565b8060ff1660f1036120695750603192915050565b8060ff1660f20361207d5750603292915050565b8060ff1660f3036120915750603392915050565b8060ff1660f4036120a55750603492915050565b8060ff1660f5036120b95750603592915050565b8060ff1660f6036120cd5750603692915050565b8060ff1660f7036120e15750603792915050565b8060ff1660f8036120f55750603892915050565b8060ff1660f9036121095750603992915050565b8060ff1660fa0361211d5750606192915050565b8060ff1660fb036121315750606292915050565b8060ff1660fc036121455750606392915050565b8060ff1660fd036121595750606492915050565b8060ff1660fe0361216d5750606592915050565b8060ff1660ff036121815750606692915050565b50919050565b82805461219390612556565b90600052602060002090601f0160209004810192826121b557600085556121fb565b82601f106121ce57805160ff19168380011785556121fb565b828001600101855582156121fb579182015b828111156121fb5782518255916020019190600101906121e0565b5061220792915061220b565b5090565b5b80821115612207576000815560010161220c565b803563ffffffff8116811461103e57600080fd5b6000806040838503121561224757600080fd5b61225083612220565b915061225e60208401612220565b90509250929050565b60008060006060848603121561227c57600080fd5b61228584612220565b925061229360208501612220565b9150604084013590509250925092565b803573ffffffffffffffffffffffffffffffffffffffff8116811461103e57600080fd5b600080604083850312156122da57600080fd5b6122e383612220565b915061225e602084016122a3565b60005b8381101561230c5781810151838201526020016122f4565b8381111561231b576000848401525b50505050565b600081518084526123398160208601602086016122f1565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006103776020830184612321565b60006020828403121561239057600080fd5b61037782612220565b6000602082840312156123ab57600080fd5b610377826122a3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156123f557600080fd5b813567ffffffffffffffff8082111561240d57600080fd5b818401915084601f83011261242157600080fd5b813581811115612433576124336123b4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715612479576124796123b4565b8160405282815287602084870101111561249257600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612522576125226124e1565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600181811c9082168061256a57607f821691505b602082108103612181577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600083516125b58184602088016122f1565b8351908301906125c98183602088016122f1565b01949350505050565b600082198211156125e5576125e56124e1565b500190565b600060ff821660ff841680821015612604576126046124e1565b90039392505050565b600060ff821660ff84168160ff048111821515161561262e5761262e6124e1565b029392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161165356fea2646970667358221220282727d67bb627ed57f2f72ef2060c7fa79561d82a651fdd63c80edd00ecd8fe64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"69313:11098:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"69313:11098:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76592:148;;;;;;:::i;:::-;;:::i;:::-;;;589:25:1;;;577:2;562:18;76592:148:0;;;;;;;;76137:267;;;;;;:::i;:::-;;:::i;77343:116::-;;;;;;:::i;:::-;;:::i;:::-;;77465:122;;;;;;:::i;:::-;;:::i;74191:276::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;68225:101::-;;;:::i;75538:353::-;;;;;;:::i;:::-;;:::i;72901:86::-;;;:::i;67593:85::-;67665:6;;67593:85;;67665:6;;;;2881:74:1;;2869:2;2854:18;67593:85:0;2735:226:1;74543:896:0;;;;;;:::i;:::-;;:::i;73787:313::-;;;;;;:::i;:::-;;:::i;71718:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;71602;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3329:10:1;3317:23;;;3299:42;;3287:2;3272:18;71602:64:0;3155:192:1;68475:198:0;;;;;;:::i;:::-;;:::i;78133:427::-;;;;;;:::i;:::-;;:::i;:::-;;;4882:14:1;;4875:22;4857:41;;4845:2;4830:18;78133:427:0;4717:187:1;76592:148:0;76693:25;;;;76667:7;76693:25;;;:16;:25;;;;;;;;:33;;;;;;;;;:40;76592:148;;;;;:::o;76137:267::-;76288:25;;;;76252:7;76288:25;;;:16;:25;;;;;;;;:33;;;;;;;;;;;:40;76279:49;;76271:68;;;;-1:-1:-1;;;76271:68:0;;5111:2:1;76271:68:0;;;5093:21:1;5150:1;5130:18;;;5123:29;5188:8;5168:18;;;5161:36;5214:18;;76271:68:0;;;;;;;;;76356:25;;;;;;;;:16;:25;;;;;;;;:33;;;;;;;;;:41;;76390:6;;76356:41;;;;;;:::i;:::-;;;;;;;;;76349:48;;76137:267;;;;;;:::o;77343:116::-;67665:6;;67805:23;67665:6;66593:10;67805:23;67797:68;;;;-1:-1:-1;;;67797:68:0;;5634:2:1;67797:68:0;;;5616:21:1;;;5653:18;;;5646:30;5712:34;5692:18;;;5685:62;5764:18;;67797:68:0;5432:356:1;67797:68:0;77424:28:::1;77435:7;77444;77424:10;:28::i;:::-;;77343:116:::0;;:::o;77465:122::-;67665:6;;67805:23;67665:6;66593:10;67805:23;67797:68;;;;-1:-1:-1;;;67797:68:0;;5634:2:1;67797:68:0;;;5616:21:1;;;5653:18;;;5646:30;5712:34;5692:18;;;5685:62;5764:18;;67797:68:0;5432:356:1;67797:68:0;77549:31:::1;77563:7;77572;77549:13;:31::i;74191:276::-:0;74314:12;74346:40;74363:7;74372:6;74380:5;74346:16;:40::i;:::-;74338:63;;;;-1:-1:-1;;;74338:63:0;;5995:2:1;74338:63:0;;;5977:21:1;6034:2;6014:18;;;6007:30;6073:12;6053:18;;;6046:40;6103:18;;74338:63:0;5793:334:1;74338:63:0;74418:42;74437:7;74446:6;74454:5;74418:18;:42::i;:::-;74411:49;74191:276;-1:-1:-1;;;;74191:276:0:o;68225:101::-;67665:6;;67805:23;67665:6;66593:10;67805:23;67797:68;;;;-1:-1:-1;;;67797:68:0;;5634:2:1;67797:68:0;;;5616:21:1;;;5653:18;;;5646:30;5712:34;5692:18;;;5685:62;5764:18;;67797:68:0;5432:356:1;67797:68:0;68289:30:::1;68316:1;68289:18;:30::i;:::-;68225:101::o:0;75538:353::-;75691:20;;;;75676:12;75691:20;;;:11;:20;;;;;;;;:29;;;;;;;;;;;75648:12;;75691:29;;75738:10;;;75730:44;;;;-1:-1:-1;;;75730:44:0;;6334:2:1;75730:44:0;;;6316:21:1;6373:2;6353:18;;;6346:30;6412:23;6392:18;;;6385:51;6453:18;;75730:44:0;6132:345:1;75730:44:0;75799:19;;;75784:12;75799:19;;;:10;:19;;;;;;;;:28;;;;;;;;;;;75844:40;75810:7;75872:5;75799:28;75844:18;:40::i;:::-;75837:47;75538:353;-1:-1:-1;;;;;75538:353:0:o;72901:86::-;62773:19;62795:25;62818:1;62795:22;:25::i;:::-;62773:47;;62834:14;62830:65;;;62864:13;:20;;;;;;;;62830:65;72954:26:::1;:24;:26::i;:::-;62919:14:::0;62915:99;;;62949:13;:21;;;;;;62989:14;;-1:-1:-1;6634:36:1;;62989:14:0;;6622:2:1;6607:18;62989:14:0;;;;;;;62915:99;62763:257;72901:86::o;74543:896::-;74661:23;;;74636:22;74661:23;;;;;;;;;;:30;74612:12;;74709:19;;;74701:41;;;;-1:-1:-1;;;74701:41:0;;6883:2:1;74701:41:0;;;6865:21:1;6922:1;6902:18;;;6895:29;6960:11;6940:18;;;6933:39;6989:18;;74701:41:0;6681:332:1;74701:41:0;74752:19;;;74814:449;74838:14;74834:1;:18;74814:449;;;74887:23;;;74870:14;74887:23;;;;;;;;;;:26;;74911:1;;74887:26;;;;;;:::i;:::-;;;;;;;;;;;;;74942:20;;;;;;:11;:20;;;;;;74887:26;;;;74942:28;;;;;;;;;;;;74887:26;;-1:-1:-1;74942:28:0;;;;75060:20;;;;75056:138;;;75114:19;;;;;;;:10;:19;;;;;;;;:27;;;;;;;;;;;75174:5;;-1:-1:-1;75114:27:0;-1:-1:-1;75174:5:0;75056:138;-1:-1:-1;;75235:3:0;;74814:449;;;;75318:12;:17;;75334:1;75318:17;75310:51;;;;-1:-1:-1;;;75310:51:0;;6334:2:1;75310:51:0;;;6316:21:1;6373:2;6353:18;;;6346:30;6412:23;6392:18;;;6385:51;6453:18;;75310:51:0;6132:345:1;75310:51:0;75378:54;75397:7;75406:12;75420:11;75378:18;:54::i;73787:313::-;73911:12;73935;73950:32;73958:7;73967:6;73975;73950:7;:32::i;:::-;73935:47;;74052:41;74071:7;74080:6;74088:4;74052:18;:41::i;68475:198::-;67665:6;;67805:23;67665:6;66593:10;67805:23;67797:68;;;;-1:-1:-1;;;67797:68:0;;5634:2:1;67797:68:0;;;5616:21:1;;;5653:18;;;5646:30;5712:34;5692:18;;;5685:62;5764:18;;67797:68:0;5432:356:1;67797:68:0;68563:22:::1;::::0;::::1;68555:73;;;::::0;-1:-1:-1;;;68555:73:0;;7220:2:1;68555:73:0::1;::::0;::::1;7202:21:1::0;7259:2;7239:18;;;7232:30;7298:34;7278:18;;;7271:62;7369:8;7349:18;;;7342:36;7395:19;;68555:73:0::1;7018:402:1::0;68555:73:0::1;68638:28;68657:8;68638:18;:28::i;78133:427::-:0;78221:22;78260:15;78277:13;78294:30;78311:12;78294:16;:30::i;:::-;78259:65;;;;78354:33;78372:7;78381:5;78354:17;:33::i;:::-;78334:53;;78401:17;78397:157;;;78521:7;78500:43;;;78530:12;78500:43;;;;;;:::i;:::-;;;;;;;;78397:157;78249:311;;78133:427;;;:::o;50841:327::-;52449:24;;;50912:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;50928:45;;-1:-1:-1;50968:5:0;50961:12;;50928:45;50983:23;;;:14;:23;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51066:23;;;:30;;51030:24;;;;;;:33;;;;;;;;;:66;;;;51111:29;2881:74:1;;;51111:29:0;;2854:18:1;51111:29:0;;;;;;;-1:-1:-1;51157:4:0;50841:327;;;;:::o;51174:1162::-;51285:24;;;51248:4;51285:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;51332:15;;;51328:33;;51356:5;51349:12;;;;;51328:33;51607:23;;;51578:26;51607:23;;;;;;;;;;;51664:14;51677:1;51664:10;:14;:::i;:::-;51708:15;;51640:38;;-1:-1:-1;51688:17:0;;51708:19;;51726:1;;51708:19;:::i;:::-;51688:39;;51754:13;51741:9;:26;51737:342;;51783:18;51804:8;51813:9;51804:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;51783:40;;51942:10;51916:8;51925:13;51916:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;:36;;;;;;;;;;;52019:24;;;;;-1:-1:-1;52019:24:0;;;;;;:36;;;;;;;;;;;;:49;;;51737:342;52149:8;:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;52229:24;;;;;;-1:-1:-1;52229:24:0;;;;;;52149:14;52229:33;;;;;;;;;;;52222:40;;;;52277:31;2881:74:1;;;52229:24:0;52277:31;;2854:18:1;52277:31:0;;;;;;;-1:-1:-1;52325:4:0;;51174:1162;-1:-1:-1;;;;;;51174:1162:0:o;79459:200::-;79607:19;;;;79584:4;79607:19;;;:10;:19;;;;;;;;:27;;;;;;;;;;;:34;;;;;;;;:41;;79584:4;;79607:34;:41;;;:::i;:::-;;;:45;79600:52;;79459:200;;;;;:::o;79106:347::-;33898:40;;;10440:66:1;10535:3;10531:16;;;10527:25;;33898:40:0;;;10515:38:1;10586:16;;;10582:25;10569:11;;;10562:46;10624:11;;;;10617:27;;;33898:40:0;;;;;;;;;;10660:12:1;;;;33898:40:0;;;79233:12;;79276:170;;79398:19;;;;;;;;:10;:19;;;;;;;;:27;;;;;;;;;;;:34;;;;;;79276:170;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:29;:170::i;68827:187::-;68919:6;;;;68935:17;;;;;;;;;;;68967:40;;68919:6;;;68935:17;68919:6;;68967:40;;68900:16;;68967:40;68890:124;68827:187;:::o;64949:808::-;65346:13;;65013:4;;65346:13;;;;;65342:409;;;65400:7;:12;;65411:1;65400:12;:61;;;;-1:-1:-1;65455:4:0;53920:19;:23;65400:61;65375:166;;;;-1:-1:-1;;;65375:166:0;;8577:2:1;65375:166:0;;;8559:21:1;8616:2;8596:18;;;8589:30;8655:34;8635:18;;;8628:62;8726:16;8706:18;;;8699:44;8760:19;;65375:166:0;8375:410:1;65375:166:0;-1:-1:-1;65562:5:0;;64949:808;-1:-1:-1;64949:808:0:o;65342:409::-;65606:12;;:22;;;;:12;;:22;65598:81;;;;-1:-1:-1;;;65598:81:0;;8577:2:1;65598:81:0;;;8559:21:1;8616:2;8596:18;;;8589:30;8655:34;8635:18;;;8628:62;8726:16;8706:18;;;8699:44;8760:19;;65598:81:0;8375:410:1;65598:81:0;-1:-1:-1;65693:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;64949:808:0:o;65342:409::-;64949:808;;;:::o;67406:111::-;64360:13;;;;;;;64352:69;;;;-1:-1:-1;;;64352:69:0;;8992:2:1;64352:69:0;;;8974:21:1;9031:2;9011:18;;;9004:30;9070:34;9050:18;;;9043:62;9141:13;9121:18;;;9114:41;9172:19;;64352:69:0;8790:407:1;64352:69:0;67478:32:::1;66593:10:::0;67478:18:::1;:32::i;47552:470::-:0;47652:16;;47707:19;:12;47652:16;47707;:19::i;:::-;47699:27;-1:-1:-1;32963:2:0;2670:26;16492:2;16488:16;;;16484:28;34217:37;47736:52;;;;-1:-1:-1;;;47736:52:0;;9404:2:1;47736:52:0;;;9386:21:1;9443:2;9423:18;;;9416:30;9482:20;9462:18;;;9455:48;9520:18;;47736:52:0;9202:342:1;47736:52:0;47809:115;47841:23;-1:-1:-1;;47841:21:0;;;:23::i;:::-;47878:36;:28;-1:-1:-1;;47878:26:0;;;:28::i;:::-;-1:-1:-1;;47878:34:0;;:36::i;:::-;47809:18;:115::i;:::-;47798:126;-1:-1:-1;47942:46:0;47952:25;-1:-1:-1;;47952:23:0;;;:25::i;:::-;52449:24;;52426:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;;;52342:152;47942:46;47934:81;;;;-1:-1:-1;;;47934:81:0;;9751:2:1;47934:81:0;;;9733:21:1;9790:2;9770:18;;;9763:30;9829:24;9809:18;;;9802:52;9871:18;;47934:81:0;9549:346:1;47934:81:0;47552:470;;;:::o;79665:744::-;79742:4;;79774:25;-1:-1:-1;;79774:23:0;;;:25::i;:::-;79758:41;-1:-1:-1;79809:12:0;79824:24;-1:-1:-1;;79824:22:0;;;:24::i;:::-;79809:39;-1:-1:-1;79858:12:0;79873:23;-1:-1:-1;;79873:21:0;;;:23::i;:::-;79922:19;;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;79858:38;;-1:-1:-1;79922:28:0;;;79914:36;;;;79906:69;;;;-1:-1:-1;;;79906:69:0;;10102:2:1;79906:69:0;;;10084:21:1;10141:2;10121:18;;;10114:30;10180:22;10160:18;;;10153:50;10220:18;;79906:69:0;9900:344:1;79906:69:0;80108:37;80125:6;80133:5;80140:4;80108:16;:37::i;:::-;80104:55;;;80154:5;80147:12;;;;;;;80104:55;80169:19;;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;:36;;;;;;;;;;;;;;80215:18;;;:10;:18;;;;;:27;;;;;;;;;:34;;;80293:36;:28;-1:-1:-1;;80293:26:0;;;:28::i;:36::-;80259:18;;;;;;;;:10;:18;;;;;;;;:25;;;;;;;;;;;:31;;;;;;;;:70;;;;:31;;:70;;;;;;:::i;:::-;-1:-1:-1;80339:24:0;;;;;;;;:16;:24;;;;;;;;:31;;;;;;;;;;;;:42;;;;;;;;;;;;;;;;;;;;79665:744;-1:-1:-1;;;79665:744:0:o;33281:196::-;33400:12;33452:5;33459:10;33435:35;;;;;;;;;:::i;:::-;;;;;;;;;;;;;33428:42;;33281:196;;;;:::o;13655:359::-;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;35074:155::-;35137:7;35163:59;-1:-1:-1;;35163:11:0;;35137:7;32963:2;35137:7;35163:11;:59::i;35312:172::-;35380:7;35406:71;32963:2;35436:37;32963:2;16492;16488:16;;;2670:26;16484:28;35436:37;:::i;:::-;-1:-1:-1;;35406:11:0;;;:71;35475:1;35406:11;:71::i;28308:632::-;28363:16;28391:11;28412:12;28427;28431:7;16492:2;16488:16;2670:26;16484:28;;16246:282;28427:12;28412:27;;;;28549:4;28543:11;28536:18;;28604:3;28597:10;;28650:33;28663:7;28672:3;28678:4;28672:10;28650:12;:33::i;:::-;-1:-1:-1;28807:14:0;;;28823:4;28803:25;28797:4;28790:39;28870:17;;28308:632;;-1:-1:-1;28308:632:0:o;46716:285::-;46826:14;;46873;-1:-1:-1;;46873:12:0;;;:14::i;:::-;46856:31;;46906:36;46935:6;45309:58;;12350:66:1;45309:58:0;;;12338:79:1;12433:12;;;12426:28;;;45179:7:0;;12470:12:1;;45309:58:0;;;;;;;;;;;;45299:69;;;;;;45292:76;;45110:265;;;;46906:36;46897:45;;46961:33;46975:6;46983:10;46961:13;:33::i;34358:143::-;34423:6;34455:38;-1:-1:-1;;34455:15:0;;34423:6;34491:1;34455:15;:38::i;34615:136::-;34679:6;34711:32;-1:-1:-1;;34711:15:0;;32857:1;;34711:15;:32::i;34844:124::-;34907:7;34933:28;-1:-1:-1;;34933:11:0;;32904:1;34958:2;34933:11;:28::i;12796:462::-;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;12065:2;12061:27;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;13212:39;11811:446;17129:399;17268:7;17287:12;17302;17306:7;15386:3;15382:17;2670:26;15378:29;;15059:364;17302:12;17287:27;;;;17398:12;17402:7;17398:3;:12::i;:::-;17391:4;17375:13;17382:6;17375:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17371:77;;;-1:-1:-1;;17426:11:0;;;;;17371:77;17465:13;17472:6;17465:4;:13;:::i;:::-;17458:20;;17495:26;17501:7;17495:26;;17510:4;17516;17495:5;:26::i;:::-;17488:33;17129:399;-1:-1:-1;;;;;;17129:399:0:o;27036:902::-;27114:15;-1:-1:-1;;7972:15:0;;;;27141:69;;;;-1:-1:-1;;;27141:69:0;;11489:2:1;27141:69:0;;;11471:21:1;11528:2;11508:18;;;11501:30;11567:34;11547:18;;;11540:62;11638:10;11618:18;;;11611:38;11666:19;;27141:69:0;11287:404:1;27141:69:0;27228:16;27236:7;27228;:16::i;:::-;27220:72;;;;-1:-1:-1;;;27220:72:0;;11898:2:1;27220:72:0;;;11880:21:1;11937:2;11917:18;;;11910:30;11976:34;11956:18;;;11949:62;12047:13;12027:18;;;12020:41;12078:19;;27220:72:0;11696:407:1;27220:72:0;27302:12;27317;27321:7;16492:2;16488:16;2670:26;16484:28;;16246:282;27317:12;27302:27;;;;27339:15;27357:12;27361:7;15386:3;15382:17;2670:26;15378:29;;15059:364;27357:12;27339:30;;;;27380:11;27501:4;27495:11;27488:18;;27588:7;27583:3;27580:16;27577:94;;;27628:4;27622;27615:18;27577:94;27843:4;27834:7;27828:4;27819:7;27816:1;27809:5;27798:50;27794:55;27879:52;27900:15;27907:7;14417:3;14413:17;;14206:268;27900:15;12061:27;12065:2;12061:27;;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;;11811:446;22455:290;22511:14;22537:12;22552;22556:7;15386:3;15382:17;2670:26;15378:29;;15059:364;22552:12;22537:27;;;;22574:12;22589;22593:7;16492:2;16488:16;2670:26;16484:28;;16246:282;22589:12;22574:27;;22708:21;;;;22455:290;-1:-1:-1;;;22455:290:0:o;41406:227::-;41484:7;41504:17;41523:18;41545:27;41556:4;41562:9;41545:10;:27::i;:::-;41503:69;;;;41582:18;41594:5;41582:11;:18::i;:::-;-1:-1:-1;41617:9:0;41406:227;-1:-1:-1;;;41406:227:0:o;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;-1:-1:-1;;;20263:76:0;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;-1:-1:-1;;;20359:83:0;;13362:2:1;20359:83:0;;;13344:21:1;13401:2;13381:18;;;13374:30;13440:34;13420:18;;;13413:62;13511:28;13491:18;;;13484:56;13557:19;;20359:83:0;13160:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;16702:147::-;16755:7;16820:12;16824:7;16492:2;16488:16;2670:26;16484:28;;16246:282;16820:12;16805;16809:7;15386:3;15382:17;2670:26;15378:29;;15059:364;16805:12;:27;16798:34;;;;16702:147;;;:::o;8645:333::-;8702:8;8726:15;8733:7;14417:3;14413:17;;14206:268;8726:15;:31;;8745:12;8726:31;8722:74;;-1:-1:-1;8780:5:0;;8645:333;-1:-1:-1;8645:333:0:o;8722:74::-;8805:12;8820;8824:7;8820:3;:12::i;:::-;8955:4;8949:11;-1:-1:-1;8936:26:0;;8645:333;-1:-1:-1;;;8645:333:0:o;39341:1279::-;39422:7;39431:12;39652:9;:16;39672:2;39652:22;39648:966;;39941:4;39926:20;;39920:27;39990:4;39975:20;;39969:27;40047:4;40032:20;;40026:27;39690:9;40018:36;40088:25;40099:4;40018:36;39920:27;39969;40088:10;:25::i;:::-;40081:32;;;;;;;;;39648:966;40134:9;:16;40154:2;40134:22;40130:484;;40403:4;40388:20;;40382:27;40453:4;40438:20;;40432:27;40493:23;40504:4;40382:27;40432;40493:10;:23::i;:::-;40486:30;;;;;;;;40130:484;-1:-1:-1;40563:1:0;;-1:-1:-1;40567:35:0;40130:484;39341:1279;;;;;:::o;37646:631::-;37723:20;37714:5;:29;;;;;;;;:::i;:::-;;37710:561;;37646:631;:::o;37710:561::-;37819:29;37810:5;:38;;;;;;;;:::i;:::-;;37806:465;;37864:34;;-1:-1:-1;;;37864:34:0;;13978:2:1;37864:34:0;;;13960:21:1;14017:2;13997:18;;;13990:30;14056:26;14036:18;;;14029:54;14100:18;;37864:34:0;13776:348:1;37806:465:0;37928:35;37919:5;:44;;;;;;;;:::i;:::-;;37915:356;;37979:41;;-1:-1:-1;;;37979:41:0;;14331:2:1;37979:41:0;;;14313:21:1;14370:2;14350:18;;;14343:30;14409:33;14389:18;;;14382:61;14460:18;;37979:41:0;14129:355:1;37915:356:0;38050:30;38041:5;:39;;;;;;;;:::i;:::-;;38037:234;;38096:44;;-1:-1:-1;;;38096:44:0;;14691:2:1;38096:44:0;;;14673:21:1;14730:2;14710:18;;;14703:30;14769:34;14749:18;;;14742:62;14840:4;14820:18;;;14813:32;14862:19;;38096:44:0;14489:398:1;38037:234:0;38170:30;38161:5;:39;;;;;;;;:::i;:::-;;38157:114;;38216:44;;-1:-1:-1;;;38216:44:0;;15094:2:1;38216:44:0;;;15076:21:1;15133:2;15113:18;;;15106:30;15172:34;15152:18;;;15145:62;15243:4;15223:18;;;15216:32;15265:19;;38216:44:0;14892:398:1;18761:741:0;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19061:33;;;19244:1;19306;19386;19448;19130:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19104:391;;18926:576;;;;18761:741;;;;;;:::o;42814:1603::-;42940:7;;43864:66;43851:79;;43847:161;;;-1:-1:-1;43962:1:0;;-1:-1:-1;43966:30:0;43946:51;;43847:161;44021:1;:7;;44026:2;44021:7;;:18;;;;;44032:1;:7;;44037:2;44032:7;;44021:18;44017:100;;;-1:-1:-1;44071:1:0;;-1:-1:-1;44075:30:0;44055:51;;44017:100;44228:24;;;44211:14;44228:24;;;;;;;;;17037:25:1;;;17110:4;17098:17;;17078:18;;;17071:45;;;;17132:18;;;17125:34;;;17175:18;;;17168:34;;;44228:24:0;;17009:19:1;;44228:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44228:24:0;;;;;;-1:-1:-1;;44266:20:0;;;44262:101;;44318:1;44322:29;44302:50;;;;;;;44262:101;44381:6;-1:-1:-1;44389:20:0;;-1:-1:-1;42814:1603:0;;;;;;;;:::o;41887:336::-;41997:7;;42055:66;42042:80;;41997:7;42148:25;42164:3;42149:18;;;42171:2;42148:25;:::i;:::-;42132:42;;42191:25;42202:4;42208:1;42211;42214;42191:10;:25::i;:::-;42184:32;;;;;;41887:336;;;;;;:::o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;2943:1393::-;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4268:57::-;3007:1329;2943:1393;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:163:1;81:20;;141:10;130:22;;120:33;;110:61;;167:1;164;157:12;182:256;248:6;256;309:2;297:9;288:7;284:23;280:32;277:52;;;325:1;322;315:12;277:52;348:28;366:9;348:28;:::i;:::-;338:38;;395:37;428:2;417:9;413:18;395:37;:::i;:::-;385:47;;182:256;;;;;:::o;625:324::-;700:6;708;716;769:2;757:9;748:7;744:23;740:32;737:52;;;785:1;782;775:12;737:52;808:28;826:9;808:28;:::i;:::-;798:38;;855:37;888:2;877:9;873:18;855:37;:::i;:::-;845:47;;939:2;928:9;924:18;911:32;901:42;;625:324;;;;;:::o;1136:196::-;1204:20;;1264:42;1253:54;;1243:65;;1233:93;;1322:1;1319;1312:12;1337:258;1404:6;1412;1465:2;1453:9;1444:7;1440:23;1436:32;1433:52;;;1481:1;1478;1471:12;1433:52;1504:28;1522:9;1504:28;:::i;:::-;1494:38;;1551;1585:2;1574:9;1570:18;1551:38;:::i;1929:258::-;2001:1;2011:113;2025:6;2022:1;2019:13;2011:113;;;2101:11;;;2095:18;2082:11;;;2075:39;2047:2;2040:10;2011:113;;;2142:6;2139:1;2136:13;2133:48;;;2177:1;2168:6;2163:3;2159:16;2152:27;2133:48;;1929:258;;;:::o;2192:316::-;2233:3;2271:5;2265:12;2298:6;2293:3;2286:19;2314:63;2370:6;2363:4;2358:3;2354:14;2347:4;2340:5;2336:16;2314:63;:::i;:::-;2422:2;2410:15;2427:66;2406:88;2397:98;;;;2497:4;2393:109;;2192:316;-1:-1:-1;;2192:316:1:o;2513:217::-;2660:2;2649:9;2642:21;2623:4;2680:44;2720:2;2709:9;2705:18;2697:6;2680:44;:::i;2966:184::-;3024:6;3077:2;3065:9;3056:7;3052:23;3048:32;3045:52;;;3093:1;3090;3083:12;3045:52;3116:28;3134:9;3116:28;:::i;3352:186::-;3411:6;3464:2;3452:9;3443:7;3439:23;3435:32;3432:52;;;3480:1;3477;3470:12;3432:52;3503:29;3522:9;3503:29;:::i;3543:184::-;3595:77;3592:1;3585:88;3692:4;3689:1;3682:15;3716:4;3713:1;3706:15;3732:980;3800:6;3853:2;3841:9;3832:7;3828:23;3824:32;3821:52;;;3869:1;3866;3859:12;3821:52;3909:9;3896:23;3938:18;3979:2;3971:6;3968:14;3965:34;;;3995:1;3992;3985:12;3965:34;4033:6;4022:9;4018:22;4008:32;;4078:7;4071:4;4067:2;4063:13;4059:27;4049:55;;4100:1;4097;4090:12;4049:55;4136:2;4123:16;4158:2;4154;4151:10;4148:36;;;4164:18;;:::i;:::-;4298:2;4292:9;4360:4;4352:13;;4203:66;4348:22;;;4372:2;4344:31;4340:40;4328:53;;;4396:18;;;4416:22;;;4393:46;4390:72;;;4442:18;;:::i;:::-;4482:10;4478:2;4471:22;4517:2;4509:6;4502:18;4557:7;4552:2;4547;4543;4539:11;4535:20;4532:33;4529:53;;;4578:1;4575;4568:12;4529:53;4634:2;4629;4625;4621:11;4616:2;4608:6;4604:15;4591:46;4679:1;4657:15;;;4674:2;4653:24;4646:35;;;;-1:-1:-1;4661:6:1;3732:980;-1:-1:-1;;;;;3732:980:1:o;5243:184::-;5295:77;5292:1;5285:88;5392:4;5389:1;5382:15;5416:4;5413:1;5406:15;7425:184;7477:77;7474:1;7467:88;7574:4;7571:1;7564:15;7598:4;7595:1;7588:15;7614:125;7654:4;7682:1;7679;7676:8;7673:34;;;7687:18;;:::i;:::-;-1:-1:-1;7724:9:1;;7614:125::o;7744:184::-;7796:77;7793:1;7786:88;7893:4;7890:1;7883:15;7917:4;7914:1;7907:15;7933:437;8012:1;8008:12;;;;8055;;;8076:61;;8130:4;8122:6;8118:17;8108:27;;8076:61;8183:2;8175:6;8172:14;8152:18;8149:38;8146:218;;8220:77;8217:1;8210:88;8321:4;8318:1;8311:15;8349:4;8346:1;8339:15;10683:466;10858:3;10896:6;10890:13;10912:53;10958:6;10953:3;10946:4;10938:6;10934:17;10912:53;:::i;:::-;11028:13;;10987:16;;;;11050:57;11028:13;10987:16;11084:4;11072:17;;11050:57;:::i;:::-;11123:20;;10683:466;-1:-1:-1;;;;10683:466:1:o;11154:128::-;11194:3;11225:1;11221:6;11218:1;11215:13;11212:39;;;11231:18;;:::i;:::-;-1:-1:-1;11267:9:1;;11154:128::o;12493:195::-;12531:4;12568;12565:1;12561:12;12600:4;12597:1;12593:12;12625:3;12620;12617:12;12614:38;;;12632:18;;:::i;:::-;12669:13;;;12493:195;-1:-1:-1;;;12493:195:1:o;12693:238::-;12731:7;12771:4;12768:1;12764:12;12803:4;12800:1;12796:12;12863:3;12857:4;12853:14;12848:3;12845:23;12838:3;12831:11;12824:19;12820:49;12817:75;;;12872:18;;:::i;:::-;12912:13;;12693:238;-1:-1:-1;;;12693:238:1:o;13587:184::-;13639:77;13636:1;13629:88;13736:4;13733:1;13726:15;13760:4;13757:1;13750:15;15414:1391;16136:34;16124:47;;16201:23;16196:2;16187:12;;16180:45;16244:66;16348:3;16344:16;;;16340:25;;16335:2;16326:12;;16319:47;16385:17;16427:2;16418:12;;16411:24;;;16469:16;;;16465:25;;16460:2;16451:12;;16444:47;16521:34;16516:2;16507:12;;16500:56;16587:3;16581;16572:13;;16565:26;16626:16;;;16622:25;;16616:3;16607:13;;16600:48;16673:3;16664:13;;16657:25;16717:16;;;16713:25;16707:3;16698:13;;16691:48;15372:3;16794;16785:13;;15360:16;-1:-1:-1;15392:11:1;;;16755:44;15295:114","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"AttestationSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_notary","type":"address"}],"name":"addNotary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"getAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_notary","type":"address"}],"name":"getLatestAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"}],"name":"getLatestAttestation","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"address","name":"","type":"address"}],"name":"latestNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"address","name":"","type":"address"}],"name":"latestRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_notary","type":"address"}],"name":"removeNotary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"}],"name":"rootsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"submitAttestation","outputs":[{"internalType":"bool","name":"attestationStored","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"getAttestation(uint32,uint32,bytes32)":{"notice":"Get attestation for (domain, nonce, root), if exists."},"getAttestation(uint32,uint32,uint256)":{"notice":"Get i-th attestation for given (domain, nonce), if exists. Assuming no fraud is committed, index = 0 should be used. If fraud was committed, there might be more than one attestation for given (domain, nonce)."},"getLatestAttestation(uint32)":{"notice":"Get latest attestation for the domain."},"getLatestAttestation(uint32,address)":{"notice":"Get latest attestation for the domain signed by given Notary."},"getRoot(uint32,uint32,uint256)":{"notice":"Get i-th root for given (domain, nonce), if exists. Assuming no fraud is committed, index = 0 should be used. If fraud was committed, there might be more than one root for given (domain, nonce)."},"rootsAmount(uint32,uint32)":{"notice":"Get amount of attested roots for given (domain, nonce). Assuming no fraud is committed, amount \u003c= 1. If amount \u003e 1, fraud was committed."}},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"attestationRoots":{"details":"All submitted Notary Attestations are stored. As different Notaries might sign attestations with the same nonce, but different root (meaning one of the attestations is fraudulent), we need a system so store all such attestations. `attestationRoots` stores a list of attested roots for every (domain, nonce) pair `signatures` stores a signature for every submitted (domain, nonce, root) attestation. We only store the first submitted signature for such attestation."},"latestNonce":{"details":"We are also storing last submitted (nonce, root) attestation for every Notary."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"AttestationSubmitted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"addNotary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"getAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"getLatestAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"}],\"name\":\"getLatestAttestation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"latestNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"latestRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"removeNotary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"}],\"name\":\"rootsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"attestationStored\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"attestationRoots\":{\"details\":\"All submitted Notary Attestations are stored. As different Notaries might sign attestations with the same nonce, but different root (meaning one of the attestations is fraudulent), we need a system so store all such attestations. `attestationRoots` stores a list of attested roots for every (domain, nonce) pair `signatures` stores a signature for every submitted (domain, nonce, root) attestation. We only store the first submitted signature for such attestation.\"},\"latestNonce\":{\"details\":\"We are also storing last submitted (nonce, root) attestation for every Notary.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getAttestation(uint32,uint32,bytes32)\":{\"notice\":\"Get attestation for (domain, nonce, root), if exists.\"},\"getAttestation(uint32,uint32,uint256)\":{\"notice\":\"Get i-th attestation for given (domain, nonce), if exists. Assuming no fraud is committed, index = 0 should be used. If fraud was committed, there might be more than one attestation for given (domain, nonce).\"},\"getLatestAttestation(uint32)\":{\"notice\":\"Get latest attestation for the domain.\"},\"getLatestAttestation(uint32,address)\":{\"notice\":\"Get latest attestation for the domain signed by given Notary.\"},\"getRoot(uint32,uint32,uint256)\":{\"notice\":\"Get i-th root for given (domain, nonce), if exists. Assuming no fraud is committed, index = 0 should be used. If fraud was committed, there might be more than one root for given (domain, nonce).\"},\"rootsAmount(uint32,uint32)\":{\"notice\":\"Get amount of attested roots for given (domain, nonce). Assuming no fraud is committed, amount \u003c= 1. If amount \u003e 1, fraud was committed.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"AttestationCollector\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{"addNotary(uint32,address)":"2af678b0","getAttestation(uint32,uint32,bytes32)":"563ffbec","getAttestation(uint32,uint32,uint256)":"bb07a791","getLatestAttestation(uint32)":"a7d729bd","getLatestAttestation(uint32,address)":"7eb2923f","getRoot(uint32,uint32,uint256)":"289def8d","initialize()":"8129fc1c","latestNonce(uint32,address)":"d53f2eec","latestRoot(uint32,address)":"d4516803","owner()":"8da5cb5b","removeNotary(uint32,address)":"4b82bad7","renounceOwnership()":"715018a6","rootsAmount(uint32,uint32)":"17007970","submitAttestation(bytes)":"f646a512","transferOwnership(address)":"f2fde38b"}},"solidity/AttestationCollector.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d5b7a52c73012a882764841613e5f3362e0d556e49785a931383b0d71dc4010964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d5b7a52c73012a882764841613e5f3362e0d556e49785a931383b0d71dc4010964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"46393:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;46393:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"46393:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220130420b187d25337d68f61342ab408fbb130895eb57445a73b06d7919fafae9b64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220130420b187d25337d68f61342ab408fbb130895eb57445a73b06d7919fafae9b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"37467:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;37467:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"37467:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:GlobalNotaryRegistry":{"code":"0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea264697066735822122046c73ffb3fd7d4a2d5c3476a63813ec913af2cb8914e234c584c98c484a7e70e64736f6c634300080d0033","runtime-code":"0x6080604052600080fdfea264697066735822122046c73ffb3fd7d4a2d5c3476a63813ec913af2cb8914e234c584c98c484a7e70e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"48125:4371:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"48125:4371:0:-:0;;;;;","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"GlobalNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"custom:oz-upgrades-unsafe-allow":"constructor constructor() { _disableInitializers(); } ``` ====","details":"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\"MyToken\", \"MTK\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\"MyToken\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```","events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor constructor() { _disableInitializers(); } ``` ====\",\"details\":\"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\\\"MyToken\\\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/AttestationCollector.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220687bf7039c5fb2337b63cd86b08f4e2ae50fa16744632f24bb6a74d66089df5f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220687bf7039c5fb2337b63cd86b08f4e2ae50fa16744632f24bb6a74d66089df5f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"35580:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;35580:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"35580:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{}},"solidity/AttestationCollector.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122053e5d99f61b8f90af9348cc4f350db2318a784e1ec61d0a8450bdc58d9da9ffc64736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122053e5d99f61b8f90af9348cc4f350db2318a784e1ec61d0a8450bdc58d9da9ffc64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\n// \ncontract AttestationCollector is GlobalNotaryRegistry, OwnableUpgradeable {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event AttestationSubmitted(address indexed updater, bytes attestation);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev All submitted Notary Attestations are stored.\n * As different Notaries might sign attestations with the same nonce,\n * but different root (meaning one of the attestations is fraudulent),\n * we need a system so store all such attestations.\n *\n * `attestationRoots` stores a list of attested roots for every (domain, nonce) pair\n * `signatures` stores a signature for every submitted (domain, nonce, root) attestation.\n * We only store the first submitted signature for such attestation.\n */\n // [homeDomain =\u003e [nonce =\u003e [roots]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e bytes32[])) internal attestationRoots;\n // [homeDomain =\u003e [nonce =\u003e [root =\u003e signature]]]\n mapping(uint32 =\u003e mapping(uint32 =\u003e mapping(bytes32 =\u003e bytes))) internal signatures;\n\n /// @dev We are also storing last submitted (nonce, root) attestation for every Notary.\n // [homeDomain =\u003e [notary =\u003e latestNonce]]\n mapping(uint32 =\u003e mapping(address =\u003e uint32)) public latestNonce;\n // [homeDomain =\u003e [notary =\u003e latestRoot]]\n mapping(uint32 =\u003e mapping(address =\u003e bytes32)) public latestRoot;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[46] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function initialize() external initializer {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Get i-th attestation for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one attestation for given (domain, nonce).\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) external view returns (bytes memory) {\n bytes32 root = getRoot(_domain, _nonce, _index);\n // signature always exists for a stored root\n return _formatAttestation(_domain, _nonce, root);\n }\n\n /**\n * @notice Get attestation for (domain, nonce, root), if exists.\n */\n function getAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) external view returns (bytes memory) {\n require(_signatureExists(_domain, _nonce, _root), \"!signature\");\n return _formatAttestation(_domain, _nonce, _root);\n }\n\n /**\n * @notice Get latest attestation for the domain.\n */\n function getLatestAttestation(uint32 _domain) external view returns (bytes memory) {\n uint256 notariesAmount = domainNotaries[_domain].length;\n require(notariesAmount != 0, \"!notaries\");\n uint32 _latestNonce = 0;\n bytes32 _latestRoot;\n for (uint256 i = 0; i \u003c notariesAmount; ) {\n address notary = domainNotaries[_domain][i];\n uint32 nonce = latestNonce[_domain][notary];\n // Check latest Notary's nonce against current latest nonce\n if (nonce \u003e _latestNonce) {\n _latestRoot = latestRoot[_domain][notary];\n _latestNonce = nonce;\n }\n unchecked {\n ++i;\n }\n }\n // Check if we found anything\n require(_latestNonce != 0, \"No attestations found\");\n return _formatAttestation(_domain, _latestNonce, _latestRoot);\n }\n\n /**\n * @notice Get latest attestation for the domain signed by given Notary.\n */\n function getLatestAttestation(uint32 _domain, address _notary)\n external\n view\n returns (bytes memory)\n {\n uint32 nonce = latestNonce[_domain][_notary];\n require(nonce != 0, \"No attestations found\");\n bytes32 root = latestRoot[_domain][_notary];\n return _formatAttestation(_domain, nonce, root);\n }\n\n /**\n * @notice Get i-th root for given (domain, nonce), if exists.\n * Assuming no fraud is committed, index = 0 should be used.\n * If fraud was committed, there might be more than one root for given (domain, nonce).\n */\n function getRoot(\n uint32 _domain,\n uint32 _nonce,\n uint256 _index\n ) public view returns (bytes32) {\n require(_index \u003c attestationRoots[_domain][_nonce].length, \"!index\");\n return attestationRoots[_domain][_nonce][_index];\n }\n\n /**\n * @notice Get amount of attested roots for given (domain, nonce).\n * Assuming no fraud is committed, amount \u003c= 1.\n * If amount \u003e 1, fraud was committed.\n */\n function rootsAmount(uint32 _domain, uint32 _nonce) external view returns (uint256) {\n return attestationRoots[_domain][_nonce].length;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // TODO: add/remove notaries upon bonding/unbonding\n\n function addNotary(uint32 _domain, address _notary) external onlyOwner {\n _addNotary(_domain, _notary);\n }\n\n function removeNotary(uint32 _domain, address _notary) external onlyOwner {\n _removeNotary(_domain, _notary);\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EXTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function submitAttestation(bytes memory _attestation)\n external\n returns (bool attestationStored)\n {\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n attestationStored = _storeAttestation(_notary, _view);\n if (attestationStored) {\n // Emit Event only if the Attestation was stored\n emit AttestationSubmitted(_notary, _attestation);\n }\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _formatAttestation(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bytes memory) {\n return\n Attestation.formatAttestation(\n Attestation.formatAttestationData(_domain, _nonce, _root),\n signatures[_domain][_nonce][_root]\n );\n }\n\n function _signatureExists(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal view returns (bool) {\n return signatures[_domain][_nonce][_root].length \u003e 0;\n }\n\n function _storeAttestation(address _notary, bytes29 _view) internal returns (bool) {\n uint32 domain = _view.attestationDomain();\n uint32 nonce = _view.attestationNonce();\n bytes32 root = _view.attestationRoot();\n require(nonce \u003e latestNonce[domain][_notary], \"Outdated attestation\");\n // Don't store Attestation, if another Notary\n // have submitted the same (domain, nonce, root) before.\n if (_signatureExists(domain, nonce, root)) return false;\n latestNonce[domain][_notary] = nonce;\n latestRoot[domain][_notary] = root;\n signatures[domain][nonce][root] = _view.attestationSignature().clone();\n attestationRoots[domain][nonce].push(root);\n return true;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/AttestationCollector.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/AttestationCollector.sol\":{\"keccak256\":\"0x804dfa89dca681130ea308dca3168c643c692b4c256f1ea640521ae404cc4491\",\"urls\":[\"bzz-raw://2bca4ab26cab3cb34c938e82e2185eef0c458fbd61f8442f0614b1309e1192a3\",\"dweb:/ipfs/QmRhSmjCgKtmdcCB11oPP4F1eK8ubzbh6bxvZT94zp5EDQ\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}}} \ No newline at end of file diff --git a/core/contracts/home/filterer_generated.go b/core/contracts/home/filterer_generated.go index fa888401d4..591bd7d3ca 100644 --- a/core/contracts/home/filterer_generated.go +++ b/core/contracts/home/filterer_generated.go @@ -25,6 +25,54 @@ type IHomeFilterer interface { // // Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) ParseDispatch(log types.Log) (*HomeDispatch, error) + // FilterDomainNotaryAdded is a free log retrieval operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. + // + // Solidity: event DomainNotaryAdded(address notary) + FilterDomainNotaryAdded(opts *bind.FilterOpts) (*HomeDomainNotaryAddedIterator, error) + // WatchDomainNotaryAdded is a free log subscription operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. + // + // Solidity: event DomainNotaryAdded(address notary) + WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *HomeDomainNotaryAdded) (event.Subscription, error) + // ParseDomainNotaryAdded is a log parse operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. + // + // Solidity: event DomainNotaryAdded(address notary) + ParseDomainNotaryAdded(log types.Log) (*HomeDomainNotaryAdded, error) + // FilterDomainNotaryRemoved is a free log retrieval operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. + // + // Solidity: event DomainNotaryRemoved(address notary) + FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*HomeDomainNotaryRemovedIterator, error) + // WatchDomainNotaryRemoved is a free log subscription operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. + // + // Solidity: event DomainNotaryRemoved(address notary) + WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *HomeDomainNotaryRemoved) (event.Subscription, error) + // ParseDomainNotaryRemoved is a log parse operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. + // + // Solidity: event DomainNotaryRemoved(address notary) + ParseDomainNotaryRemoved(log types.Log) (*HomeDomainNotaryRemoved, error) + // FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. + // + // Solidity: event GuardAdded(address guard) + FilterGuardAdded(opts *bind.FilterOpts) (*HomeGuardAddedIterator, error) + // WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. + // + // Solidity: event GuardAdded(address guard) + WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *HomeGuardAdded) (event.Subscription, error) + // ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. + // + // Solidity: event GuardAdded(address guard) + ParseGuardAdded(log types.Log) (*HomeGuardAdded, error) + // FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. + // + // Solidity: event GuardRemoved(address guard) + FilterGuardRemoved(opts *bind.FilterOpts) (*HomeGuardRemovedIterator, error) + // WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. + // + // Solidity: event GuardRemoved(address guard) + WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *HomeGuardRemoved) (event.Subscription, error) + // ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. + // + // Solidity: event GuardRemoved(address guard) + ParseGuardRemoved(log types.Log) (*HomeGuardRemoved, error) // FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. // // Solidity: event ImproperAttestation(address updater, bytes attestation) @@ -49,18 +97,6 @@ type IHomeFilterer interface { // // Solidity: event Initialized(uint8 version) ParseInitialized(log types.Log) (*HomeInitialized, error) - // FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. - // - // Solidity: event NewUpdater(address oldUpdater, address newUpdater) - FilterNewUpdater(opts *bind.FilterOpts) (*HomeNewUpdaterIterator, error) - // WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. - // - // Solidity: event NewUpdater(address oldUpdater, address newUpdater) - WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *HomeNewUpdater) (event.Subscription, error) - // ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. - // - // Solidity: event NewUpdater(address oldUpdater, address newUpdater) - ParseNewUpdater(log types.Log) (*HomeNewUpdater, error) // FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. // // Solidity: event NewUpdaterManager(address updaterManager) @@ -85,18 +121,6 @@ type IHomeFilterer interface { // // Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) ParseOwnershipTransferred(log types.Log) (*HomeOwnershipTransferred, error) - // FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. - // - // Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) - FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*HomeUpdateIterator, error) - // WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. - // - // Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) - WatchUpdate(opts *bind.WatchOpts, sink chan<- *HomeUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) - // ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. - // - // Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) - ParseUpdate(log types.Log) (*HomeUpdate, error) // FilterUpdaterSlashed is a free log retrieval operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. // // Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) diff --git a/core/contracts/home/home.abigen.go b/core/contracts/home/home.abigen.go index 33b7d56e33..3cdbdfa7f6 100644 --- a/core/contracts/home/home.abigen.go +++ b/core/contracts/home/home.abigen.go @@ -28,10 +28,312 @@ var ( _ = event.NewSubscription ) +// AbstractGuardRegistryMetaData contains all meta data concerning the AbstractGuardRegistry contract. +var AbstractGuardRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractGuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractGuardRegistryMetaData.ABI instead. +var AbstractGuardRegistryABI = AbstractGuardRegistryMetaData.ABI + +// AbstractGuardRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractGuardRegistry struct { + AbstractGuardRegistryCaller // Read-only binding to the contract + AbstractGuardRegistryTransactor // Write-only binding to the contract + AbstractGuardRegistryFilterer // Log filterer for contract events +} + +// AbstractGuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractGuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractGuardRegistrySession struct { + Contract *AbstractGuardRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractGuardRegistryCallerSession struct { + Contract *AbstractGuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractGuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractGuardRegistryTransactorSession struct { + Contract *AbstractGuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractGuardRegistryRaw struct { + Contract *AbstractGuardRegistry // Generic contract binding to access the raw methods on +} + +// AbstractGuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCallerRaw struct { + Contract *AbstractGuardRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractGuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactorRaw struct { + Contract *AbstractGuardRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractGuardRegistry creates a new instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistry(address common.Address, backend bind.ContractBackend) (*AbstractGuardRegistry, error) { + contract, err := bindAbstractGuardRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractGuardRegistry{AbstractGuardRegistryCaller: AbstractGuardRegistryCaller{contract: contract}, AbstractGuardRegistryTransactor: AbstractGuardRegistryTransactor{contract: contract}, AbstractGuardRegistryFilterer: AbstractGuardRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractGuardRegistryCaller creates a new read-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractGuardRegistryCaller, error) { + contract, err := bindAbstractGuardRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryCaller{contract: contract}, nil +} + +// NewAbstractGuardRegistryTransactor creates a new write-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractGuardRegistryTransactor, error) { + contract, err := bindAbstractGuardRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryTransactor{contract: contract}, nil +} + +// NewAbstractGuardRegistryFilterer creates a new log filterer instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractGuardRegistryFilterer, error) { + contract, err := bindAbstractGuardRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryFilterer{contract: contract}, nil +} + +// bindAbstractGuardRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractGuardRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transact(opts, method, params...) +} + +// AbstractNotaryRegistryMetaData contains all meta data concerning the AbstractNotaryRegistry contract. +var AbstractNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractNotaryRegistryMetaData.ABI instead. +var AbstractNotaryRegistryABI = AbstractNotaryRegistryMetaData.ABI + +// AbstractNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractNotaryRegistry struct { + AbstractNotaryRegistryCaller // Read-only binding to the contract + AbstractNotaryRegistryTransactor // Write-only binding to the contract + AbstractNotaryRegistryFilterer // Log filterer for contract events +} + +// AbstractNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractNotaryRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractNotaryRegistrySession struct { + Contract *AbstractNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractNotaryRegistryCallerSession struct { + Contract *AbstractNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractNotaryRegistryTransactorSession struct { + Contract *AbstractNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractNotaryRegistryRaw struct { + Contract *AbstractNotaryRegistry // Generic contract binding to access the raw methods on +} + +// AbstractNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCallerRaw struct { + Contract *AbstractNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactorRaw struct { + Contract *AbstractNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractNotaryRegistry creates a new instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistry(address common.Address, backend bind.ContractBackend) (*AbstractNotaryRegistry, error) { + contract, err := bindAbstractNotaryRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistry{AbstractNotaryRegistryCaller: AbstractNotaryRegistryCaller{contract: contract}, AbstractNotaryRegistryTransactor: AbstractNotaryRegistryTransactor{contract: contract}, AbstractNotaryRegistryFilterer: AbstractNotaryRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractNotaryRegistryCaller creates a new read-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractNotaryRegistryCaller, error) { + contract, err := bindAbstractNotaryRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryCaller{contract: contract}, nil +} + +// NewAbstractNotaryRegistryTransactor creates a new write-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractNotaryRegistryTransactor, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryTransactor{contract: contract}, nil +} + +// NewAbstractNotaryRegistryFilterer creates a new log filterer instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractNotaryRegistryFilterer, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryFilterer{contract: contract}, nil +} + +// bindAbstractNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractNotaryRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transact(opts, method, params...) +} + // AddressMetaData contains all meta data concerning the Address contract. var AddressMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220854d99b9e1772a582bb7f179bbc72ab60a19d5a9c8c31114f5d0ce41943177ba64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a31bdd6619397ba0f7531e5b3cb1bcb23234fe47d1c82e9187a5205ef5b1d88164736f6c634300080d0033", } // AddressABI is the input ABI used to generate the binding from. @@ -204,7 +506,7 @@ func (_Address *AddressTransactorRaw) Transact(opts *bind.TransactOpts, method s // AddressUpgradeableMetaData contains all meta data concerning the AddressUpgradeable contract. var AddressUpgradeableMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208f6e8c5d5e570a09438453c278bf2a3367e949e075723f8b4687f291d788d0f964736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220372f28fd136caf4eb520ca25524adcfa0a45c183eba12437cc26a498015a2e9464736f6c634300080d0033", } // AddressUpgradeableABI is the input ABI used to generate the binding from. @@ -377,7 +679,7 @@ func (_AddressUpgradeable *AddressUpgradeableTransactorRaw) Transact(opts *bind. // AttestationMetaData contains all meta data concerning the Attestation contract. var AttestationMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a33850447495ba5898fec6f32aaada16448f91bd7c415fdddf1f853041113b7764736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c94353cfcbcddb3ecb41e58c1ba984e4c5ffe990405fea301773c4f326bd14e064736f6c634300080d0033", } // AttestationABI is the input ABI used to generate the binding from. @@ -550,7 +852,7 @@ func (_Attestation *AttestationTransactorRaw) Transact(opts *bind.TransactOpts, // AuthMetaData contains all meta data concerning the Auth contract. var AuthMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122088dedff94379c65ec0f5e9cca1e016a7c559c6466418a6c05dd1facd4682709e64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122072a0ed4f918458a0cf4c1dcac03516b8775621101ee2182a92af4428b0b4482564736f6c634300080d0033", } // AuthABI is the input ABI used to generate the binding from. @@ -720,157 +1022,6 @@ func (_Auth *AuthTransactorRaw) Transact(opts *bind.TransactOpts, method string, return _Auth.Contract.contract.Transact(opts, method, params...) } -// AuthManagerMetaData contains all meta data concerning the AuthManager contract. -var AuthManagerMetaData = &bind.MetaData{ - ABI: "[]", -} - -// AuthManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use AuthManagerMetaData.ABI instead. -var AuthManagerABI = AuthManagerMetaData.ABI - -// AuthManager is an auto generated Go binding around an Ethereum contract. -type AuthManager struct { - AuthManagerCaller // Read-only binding to the contract - AuthManagerTransactor // Write-only binding to the contract - AuthManagerFilterer // Log filterer for contract events -} - -// AuthManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type AuthManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type AuthManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type AuthManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type AuthManagerSession struct { - Contract *AuthManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type AuthManagerCallerSession struct { - Contract *AuthManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// AuthManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type AuthManagerTransactorSession struct { - Contract *AuthManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type AuthManagerRaw struct { - Contract *AuthManager // Generic contract binding to access the raw methods on -} - -// AuthManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type AuthManagerCallerRaw struct { - Contract *AuthManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// AuthManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type AuthManagerTransactorRaw struct { - Contract *AuthManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewAuthManager creates a new instance of AuthManager, bound to a specific deployed contract. -func NewAuthManager(address common.Address, backend bind.ContractBackend) (*AuthManager, error) { - contract, err := bindAuthManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &AuthManager{AuthManagerCaller: AuthManagerCaller{contract: contract}, AuthManagerTransactor: AuthManagerTransactor{contract: contract}, AuthManagerFilterer: AuthManagerFilterer{contract: contract}}, nil -} - -// NewAuthManagerCaller creates a new read-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerCaller(address common.Address, caller bind.ContractCaller) (*AuthManagerCaller, error) { - contract, err := bindAuthManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &AuthManagerCaller{contract: contract}, nil -} - -// NewAuthManagerTransactor creates a new write-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*AuthManagerTransactor, error) { - contract, err := bindAuthManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &AuthManagerTransactor{contract: contract}, nil -} - -// NewAuthManagerFilterer creates a new log filterer instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*AuthManagerFilterer, error) { - contract, err := bindAuthManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &AuthManagerFilterer{contract: contract}, nil -} - -// bindAuthManager binds a generic wrapper to an already deployed contract. -func bindAuthManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(AuthManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.AuthManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transact(opts, method, params...) -} - // ContextUpgradeableMetaData contains all meta data concerning the ContextUpgradeable contract. var ContextUpgradeableMetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", @@ -1156,23 +1307,32 @@ func (_ContextUpgradeable *ContextUpgradeableFilterer) ParseInitialized(log type return event, nil } -// ECDSAMetaData contains all meta data concerning the ECDSA contract. -var ECDSAMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206f9d8415999e703353a5cf87a07ced8e4954b1ee8a0ecc7a228eb46deef1fca564736f6c634300080d0033", -} +// DomainNotaryRegistryMetaData contains all meta data concerning the DomainNotaryRegistry contract. +var DomainNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_trackedDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "9817e315": "allNotaries()", + "c07dc7f5": "getNotary(uint256)", + "8e62e9ef": "notariesAmount()", + }, + Bin: "0x60a060405234801561001057600080fd5b506040516102e73803806102e783398101604081905261002f9161003d565b63ffffffff1660805261006a565b60006020828403121561004f57600080fd5b815163ffffffff8116811461006357600080fd5b9392505050565b608051610265610082600039600050506102656000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220f0358fecc3302bdb6fbcb411209862a283459b9383dac3ee9b6f7fa9a32dfffe64736f6c634300080d0033", +} -// ECDSAABI is the input ABI used to generate the binding from. -// Deprecated: Use ECDSAMetaData.ABI instead. -var ECDSAABI = ECDSAMetaData.ABI +// DomainNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use DomainNotaryRegistryMetaData.ABI instead. +var DomainNotaryRegistryABI = DomainNotaryRegistryMetaData.ABI -// ECDSABin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ECDSAMetaData.Bin instead. -var ECDSABin = ECDSAMetaData.Bin +// Deprecated: Use DomainNotaryRegistryMetaData.Sigs instead. +// DomainNotaryRegistryFuncSigs maps the 4-byte function signature to its string representation. +var DomainNotaryRegistryFuncSigs = DomainNotaryRegistryMetaData.Sigs -// DeployECDSA deploys a new Ethereum contract, binding an instance of ECDSA to it. -func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ECDSA, error) { - parsed, err := ECDSAMetaData.GetAbi() +// DomainNotaryRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use DomainNotaryRegistryMetaData.Bin instead. +var DomainNotaryRegistryBin = DomainNotaryRegistryMetaData.Bin + +// DeployDomainNotaryRegistry deploys a new Ethereum contract, binding an instance of DomainNotaryRegistry to it. +func DeployDomainNotaryRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, _trackedDomain uint32) (common.Address, *types.Transaction, *DomainNotaryRegistry, error) { + parsed, err := DomainNotaryRegistryMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1180,111 +1340,111 @@ func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common. return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ECDSABin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DomainNotaryRegistryBin), backend, _trackedDomain) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil + return address, tx, &DomainNotaryRegistry{DomainNotaryRegistryCaller: DomainNotaryRegistryCaller{contract: contract}, DomainNotaryRegistryTransactor: DomainNotaryRegistryTransactor{contract: contract}, DomainNotaryRegistryFilterer: DomainNotaryRegistryFilterer{contract: contract}}, nil } -// ECDSA is an auto generated Go binding around an Ethereum contract. -type ECDSA struct { - ECDSACaller // Read-only binding to the contract - ECDSATransactor // Write-only binding to the contract - ECDSAFilterer // Log filterer for contract events +// DomainNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type DomainNotaryRegistry struct { + DomainNotaryRegistryCaller // Read-only binding to the contract + DomainNotaryRegistryTransactor // Write-only binding to the contract + DomainNotaryRegistryFilterer // Log filterer for contract events } -// ECDSACaller is an auto generated read-only Go binding around an Ethereum contract. -type ECDSACaller struct { +// DomainNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type DomainNotaryRegistryCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSATransactor is an auto generated write-only Go binding around an Ethereum contract. -type ECDSATransactor struct { +// DomainNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type DomainNotaryRegistryTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSAFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ECDSAFilterer struct { +// DomainNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type DomainNotaryRegistryFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSASession is an auto generated Go binding around an Ethereum contract, +// DomainNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ECDSASession struct { - Contract *ECDSA // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type DomainNotaryRegistrySession struct { + Contract *DomainNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ECDSACallerSession is an auto generated read-only Go binding around an Ethereum contract, +// DomainNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ECDSACallerSession struct { - Contract *ECDSACaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type DomainNotaryRegistryCallerSession struct { + Contract *DomainNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ECDSATransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// DomainNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ECDSATransactorSession struct { - Contract *ECDSATransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type DomainNotaryRegistryTransactorSession struct { + Contract *DomainNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ECDSARaw is an auto generated low-level Go binding around an Ethereum contract. -type ECDSARaw struct { - Contract *ECDSA // Generic contract binding to access the raw methods on +// DomainNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type DomainNotaryRegistryRaw struct { + Contract *DomainNotaryRegistry // Generic contract binding to access the raw methods on } -// ECDSACallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ECDSACallerRaw struct { - Contract *ECDSACaller // Generic read-only contract binding to access the raw methods on +// DomainNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type DomainNotaryRegistryCallerRaw struct { + Contract *DomainNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on } -// ECDSATransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ECDSATransactorRaw struct { - Contract *ECDSATransactor // Generic write-only contract binding to access the raw methods on +// DomainNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type DomainNotaryRegistryTransactorRaw struct { + Contract *DomainNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on } -// NewECDSA creates a new instance of ECDSA, bound to a specific deployed contract. -func NewECDSA(address common.Address, backend bind.ContractBackend) (*ECDSA, error) { - contract, err := bindECDSA(address, backend, backend, backend) +// NewDomainNotaryRegistry creates a new instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistry(address common.Address, backend bind.ContractBackend) (*DomainNotaryRegistry, error) { + contract, err := bindDomainNotaryRegistry(address, backend, backend, backend) if err != nil { return nil, err } - return &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil + return &DomainNotaryRegistry{DomainNotaryRegistryCaller: DomainNotaryRegistryCaller{contract: contract}, DomainNotaryRegistryTransactor: DomainNotaryRegistryTransactor{contract: contract}, DomainNotaryRegistryFilterer: DomainNotaryRegistryFilterer{contract: contract}}, nil } -// NewECDSACaller creates a new read-only instance of ECDSA, bound to a specific deployed contract. -func NewECDSACaller(address common.Address, caller bind.ContractCaller) (*ECDSACaller, error) { - contract, err := bindECDSA(address, caller, nil, nil) +// NewDomainNotaryRegistryCaller creates a new read-only instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*DomainNotaryRegistryCaller, error) { + contract, err := bindDomainNotaryRegistry(address, caller, nil, nil) if err != nil { return nil, err } - return &ECDSACaller{contract: contract}, nil + return &DomainNotaryRegistryCaller{contract: contract}, nil } -// NewECDSATransactor creates a new write-only instance of ECDSA, bound to a specific deployed contract. -func NewECDSATransactor(address common.Address, transactor bind.ContractTransactor) (*ECDSATransactor, error) { - contract, err := bindECDSA(address, nil, transactor, nil) +// NewDomainNotaryRegistryTransactor creates a new write-only instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*DomainNotaryRegistryTransactor, error) { + contract, err := bindDomainNotaryRegistry(address, nil, transactor, nil) if err != nil { return nil, err } - return &ECDSATransactor{contract: contract}, nil + return &DomainNotaryRegistryTransactor{contract: contract}, nil } -// NewECDSAFilterer creates a new log filterer instance of ECDSA, bound to a specific deployed contract. -func NewECDSAFilterer(address common.Address, filterer bind.ContractFilterer) (*ECDSAFilterer, error) { - contract, err := bindECDSA(address, nil, nil, filterer) +// NewDomainNotaryRegistryFilterer creates a new log filterer instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*DomainNotaryRegistryFilterer, error) { + contract, err := bindDomainNotaryRegistry(address, nil, nil, filterer) if err != nil { return nil, err } - return &ECDSAFilterer{contract: contract}, nil + return &DomainNotaryRegistryFilterer{contract: contract}, nil } -// bindECDSA binds a generic wrapper to an already deployed contract. -func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ECDSAABI)) +// bindDomainNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindDomainNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(DomainNotaryRegistryABI)) if err != nil { return nil, err } @@ -1295,258 +1455,418 @@ func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bi // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ECDSA *ECDSARaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ECDSA.Contract.ECDSACaller.contract.Call(opts, result, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ECDSA *ECDSARaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ECDSA.Contract.ECDSATransactor.contract.Transfer(opts) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ECDSA *ECDSARaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ECDSA.Contract.ECDSATransactor.contract.Transact(opts, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ECDSA *ECDSACallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ECDSA.Contract.contract.Call(opts, result, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DomainNotaryRegistry.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ECDSA *ECDSATransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ECDSA.Contract.contract.Transfer(opts) +func (_DomainNotaryRegistry *DomainNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ECDSA.Contract.contract.Transact(opts, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.contract.Transact(opts, method, params...) } -// HeaderMetaData contains all meta data concerning the Header contract. -var HeaderMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202e677156b343adc866709487e1813ebe40c4d10a6a8e096fac1ffb6a59693f3364736f6c634300080d0033", +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) AllNotaries(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "allNotaries") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + } -// HeaderABI is the input ABI used to generate the binding from. -// Deprecated: Use HeaderMetaData.ABI instead. -var HeaderABI = HeaderMetaData.ABI +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) AllNotaries() ([]common.Address, error) { + return _DomainNotaryRegistry.Contract.AllNotaries(&_DomainNotaryRegistry.CallOpts) +} -// HeaderBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HeaderMetaData.Bin instead. -var HeaderBin = HeaderMetaData.Bin +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) AllNotaries() ([]common.Address, error) { + return _DomainNotaryRegistry.Contract.AllNotaries(&_DomainNotaryRegistry.CallOpts) +} -// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. -func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { - parsed, err := HeaderMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "getNotary", _index) - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) if err != nil { - return common.Address{}, nil, nil, err + return *new(common.Address), err } - return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil -} -// Header is an auto generated Go binding around an Ethereum contract. -type Header struct { - HeaderCaller // Read-only binding to the contract - HeaderTransactor // Write-only binding to the contract - HeaderFilterer // Log filterer for contract events -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err -// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. -type HeaderCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HeaderTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) GetNotary(_index *big.Int) (common.Address, error) { + return _DomainNotaryRegistry.Contract.GetNotary(&_DomainNotaryRegistry.CallOpts, _index) } -// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HeaderFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) GetNotary(_index *big.Int) (common.Address, error) { + return _DomainNotaryRegistry.Contract.GetNotary(&_DomainNotaryRegistry.CallOpts, _index) } -// HeaderSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type HeaderSession struct { - Contract *Header // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) NotariesAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "notariesAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type HeaderCallerSession struct { - Contract *HeaderCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) NotariesAmount() (*big.Int, error) { + return _DomainNotaryRegistry.Contract.NotariesAmount(&_DomainNotaryRegistry.CallOpts) } -// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type HeaderTransactorSession struct { - Contract *HeaderTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) NotariesAmount() (*big.Int, error) { + return _DomainNotaryRegistry.Contract.NotariesAmount(&_DomainNotaryRegistry.CallOpts) } -// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. -type HeaderRaw struct { - Contract *Header // Generic contract binding to access the raw methods on +// DomainNotaryRegistryDomainNotaryAddedIterator is returned from FilterDomainNotaryAdded and is used to iterate over the raw logs and unpacked data for DomainNotaryAdded events raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryAddedIterator struct { + Event *DomainNotaryRegistryDomainNotaryAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HeaderCallerRaw struct { - Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HeaderTransactorRaw struct { - Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Error() error { + return it.fail } -// NewHeader creates a new instance of Header, bound to a specific deployed contract. -func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { - contract, err := bindHeader(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. -func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { - contract, err := bindHeader(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &HeaderCaller{contract: contract}, nil +// DomainNotaryRegistryDomainNotaryAdded represents a DomainNotaryAdded event raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryAdded struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. -func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { - contract, err := bindHeader(address, nil, transactor, nil) +// FilterDomainNotaryAdded is a free log retrieval operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) FilterDomainNotaryAdded(opts *bind.FilterOpts) (*DomainNotaryRegistryDomainNotaryAddedIterator, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.FilterLogs(opts, "DomainNotaryAdded") if err != nil { return nil, err } - return &HeaderTransactor{contract: contract}, nil + return &DomainNotaryRegistryDomainNotaryAddedIterator{contract: _DomainNotaryRegistry.contract, event: "DomainNotaryAdded", logs: logs, sub: sub}, nil } -// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. -func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { - contract, err := bindHeader(address, nil, nil, filterer) +// WatchDomainNotaryAdded is a free log subscription operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *DomainNotaryRegistryDomainNotaryAdded) (event.Subscription, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.WatchLogs(opts, "DomainNotaryAdded") if err != nil { return nil, err } - return &HeaderFilterer{contract: contract}, nil -} - -// bindHeader binds a generic wrapper to an already deployed contract. -func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HeaderABI)) - if err != nil { + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DomainNotaryRegistryDomainNotaryAdded) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDomainNotaryAdded is a log parse operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) ParseDomainNotaryAdded(log types.Log) (*DomainNotaryRegistryDomainNotaryAdded, error) { + event := new(DomainNotaryRegistryDomainNotaryAdded) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + event.Raw = log + return event, nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) +// DomainNotaryRegistryDomainNotaryRemovedIterator is returned from FilterDomainNotaryRemoved and is used to iterate over the raw logs and unpacked data for DomainNotaryRemoved events raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryRemovedIterator struct { + Event *DomainNotaryRegistryDomainNotaryRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transfer(opts) +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Error() error { + return it.fail } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.contract.Call(opts, result, method, params...) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.contract.Transfer(opts) +// DomainNotaryRegistryDomainNotaryRemoved represents a DomainNotaryRemoved event raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryRemoved struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.contract.Transact(opts, method, params...) +// FilterDomainNotaryRemoved is a free log retrieval operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*DomainNotaryRegistryDomainNotaryRemovedIterator, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.FilterLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return &DomainNotaryRegistryDomainNotaryRemovedIterator{contract: _DomainNotaryRegistry.contract, event: "DomainNotaryRemoved", logs: logs, sub: sub}, nil } -// HomeMetaData contains all meta data concerning the Home contract. -var HomeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enumHome.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "522ae002": "MAX_MESSAGE_BODY_BYTES()", - "ffa1ad74": "VERSION()", - "06661abd": "count()", - "f7560e40": "dispatch(uint32,bytes32,uint32,bytes,bytes)", - "7ea97f40": "historicalRoots(uint256)", - "0afe7f90": "improperAttestation(bytes)", - "c4d66de8": "initialize(address)", - "8d3638f4": "localDomain()", - "affed0e0": "nonce()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "ebf0c717": "root()", - "b7bc563e": "setSystemMessenger(address)", - "9d54f419": "setUpdater(address)", - "9776120e": "setUpdaterManager(address)", - "c19d93fb": "state()", - "36e104de": "suggestUpdate()", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "fd54b228": "tree()", - "df034cd0": "updater()", - "9df6c8e1": "updaterManager()", - }, - Bin: "0x60a06040523480156200001157600080fd5b50604051620036d9380380620036d9833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b60805161363d6200009c6000396000818161025e01528181610d9c01526117a3015261363d6000f3fe6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220b22f209b5f062fc859601394f10100b84c7771bbdf8c9334225113abaf846cbf64736f6c634300080d0033", +// WatchDomainNotaryRemoved is a free log subscription operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *DomainNotaryRegistryDomainNotaryRemoved) (event.Subscription, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.WatchLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DomainNotaryRegistryDomainNotaryRemoved) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// HomeABI is the input ABI used to generate the binding from. -// Deprecated: Use HomeMetaData.ABI instead. -var HomeABI = HomeMetaData.ABI +// ParseDomainNotaryRemoved is a log parse operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) ParseDomainNotaryRemoved(log types.Log) (*DomainNotaryRegistryDomainNotaryRemoved, error) { + event := new(DomainNotaryRegistryDomainNotaryRemoved) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} -// Deprecated: Use HomeMetaData.Sigs instead. -// HomeFuncSigs maps the 4-byte function signature to its string representation. -var HomeFuncSigs = HomeMetaData.Sigs +// ECDSAMetaData contains all meta data concerning the ECDSA contract. +var ECDSAMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202a58c00b5b08e7ab17206accdfa1a4ab9495ccfc6cb68f21a1d8091082e371f564736f6c634300080d0033", +} -// HomeBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HomeMetaData.Bin instead. -var HomeBin = HomeMetaData.Bin +// ECDSAABI is the input ABI used to generate the binding from. +// Deprecated: Use ECDSAMetaData.ABI instead. +var ECDSAABI = ECDSAMetaData.ABI -// DeployHome deploys a new Ethereum contract, binding an instance of Home to it. -func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *Home, error) { - parsed, err := HomeMetaData.GetAbi() +// ECDSABin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ECDSAMetaData.Bin instead. +var ECDSABin = ECDSAMetaData.Bin + +// DeployECDSA deploys a new Ethereum contract, binding an instance of ECDSA to it. +func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ECDSA, error) { + parsed, err := ECDSAMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1554,111 +1874,111 @@ func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDom return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HomeBin), backend, _localDomain) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ECDSABin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil + return address, tx, &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil } -// Home is an auto generated Go binding around an Ethereum contract. -type Home struct { - HomeCaller // Read-only binding to the contract - HomeTransactor // Write-only binding to the contract - HomeFilterer // Log filterer for contract events +// ECDSA is an auto generated Go binding around an Ethereum contract. +type ECDSA struct { + ECDSACaller // Read-only binding to the contract + ECDSATransactor // Write-only binding to the contract + ECDSAFilterer // Log filterer for contract events } -// HomeCaller is an auto generated read-only Go binding around an Ethereum contract. -type HomeCaller struct { +// ECDSACaller is an auto generated read-only Go binding around an Ethereum contract. +type ECDSACaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HomeTransactor struct { +// ECDSATransactor is an auto generated write-only Go binding around an Ethereum contract. +type ECDSATransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HomeFilterer struct { +// ECDSAFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ECDSAFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeSession is an auto generated Go binding around an Ethereum contract, +// ECDSASession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type HomeSession struct { - Contract *Home // Generic contract binding to set the session for +type ECDSASession struct { + Contract *ECDSA // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// ECDSACallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type HomeCallerSession struct { - Contract *HomeCaller // Generic contract caller binding to set the session for +type ECDSACallerSession struct { + Contract *ECDSACaller // Generic contract caller binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session } -// HomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// ECDSATransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type HomeTransactorSession struct { - Contract *HomeTransactor // Generic contract transactor binding to set the session for +type ECDSATransactorSession struct { + Contract *ECDSATransactor // Generic contract transactor binding to set the session for TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HomeRaw is an auto generated low-level Go binding around an Ethereum contract. -type HomeRaw struct { - Contract *Home // Generic contract binding to access the raw methods on -} - -// HomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HomeCallerRaw struct { - Contract *HomeCaller // Generic read-only contract binding to access the raw methods on +// ECDSARaw is an auto generated low-level Go binding around an Ethereum contract. +type ECDSARaw struct { + Contract *ECDSA // Generic contract binding to access the raw methods on } -// HomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HomeTransactorRaw struct { - Contract *HomeTransactor // Generic write-only contract binding to access the raw methods on +// ECDSACallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ECDSACallerRaw struct { + Contract *ECDSACaller // Generic read-only contract binding to access the raw methods on } -// NewHome creates a new instance of Home, bound to a specific deployed contract. -func NewHome(address common.Address, backend bind.ContractBackend) (*Home, error) { - contract, err := bindHome(address, backend, backend, backend) +// ECDSATransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ECDSATransactorRaw struct { + Contract *ECDSATransactor // Generic write-only contract binding to access the raw methods on +} + +// NewECDSA creates a new instance of ECDSA, bound to a specific deployed contract. +func NewECDSA(address common.Address, backend bind.ContractBackend) (*ECDSA, error) { + contract, err := bindECDSA(address, backend, backend, backend) if err != nil { return nil, err } - return &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil + return &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil } -// NewHomeCaller creates a new read-only instance of Home, bound to a specific deployed contract. -func NewHomeCaller(address common.Address, caller bind.ContractCaller) (*HomeCaller, error) { - contract, err := bindHome(address, caller, nil, nil) +// NewECDSACaller creates a new read-only instance of ECDSA, bound to a specific deployed contract. +func NewECDSACaller(address common.Address, caller bind.ContractCaller) (*ECDSACaller, error) { + contract, err := bindECDSA(address, caller, nil, nil) if err != nil { return nil, err } - return &HomeCaller{contract: contract}, nil + return &ECDSACaller{contract: contract}, nil } -// NewHomeTransactor creates a new write-only instance of Home, bound to a specific deployed contract. -func NewHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*HomeTransactor, error) { - contract, err := bindHome(address, nil, transactor, nil) +// NewECDSATransactor creates a new write-only instance of ECDSA, bound to a specific deployed contract. +func NewECDSATransactor(address common.Address, transactor bind.ContractTransactor) (*ECDSATransactor, error) { + contract, err := bindECDSA(address, nil, transactor, nil) if err != nil { return nil, err } - return &HomeTransactor{contract: contract}, nil + return &ECDSATransactor{contract: contract}, nil } -// NewHomeFilterer creates a new log filterer instance of Home, bound to a specific deployed contract. -func NewHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*HomeFilterer, error) { - contract, err := bindHome(address, nil, nil, filterer) +// NewECDSAFilterer creates a new log filterer instance of ECDSA, bound to a specific deployed contract. +func NewECDSAFilterer(address common.Address, filterer bind.ContractFilterer) (*ECDSAFilterer, error) { + contract, err := bindECDSA(address, nil, nil, filterer) if err != nil { return nil, err } - return &HomeFilterer{contract: contract}, nil + return &ECDSAFilterer{contract: contract}, nil } -// bindHome binds a generic wrapper to an already deployed contract. -func bindHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HomeABI)) +// bindECDSA binds a generic wrapper to an already deployed contract. +func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ECDSAABI)) if err != nil { return nil, err } @@ -1669,370 +1989,432 @@ func bindHome(address common.Address, caller bind.ContractCaller, transactor bin // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Home *HomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Home.Contract.HomeCaller.contract.Call(opts, result, method, params...) +func (_ECDSA *ECDSARaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ECDSA.Contract.ECDSACaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Home *HomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.Contract.HomeTransactor.contract.Transfer(opts) +func (_ECDSA *ECDSARaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ECDSA.Contract.ECDSATransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Home *HomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Home.Contract.HomeTransactor.contract.Transact(opts, method, params...) +func (_ECDSA *ECDSARaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ECDSA.Contract.ECDSATransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Home *HomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Home.Contract.contract.Call(opts, result, method, params...) +func (_ECDSA *ECDSACallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ECDSA.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Home *HomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.Contract.contract.Transfer(opts) +func (_ECDSA *ECDSATransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ECDSA.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Home *HomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Home.Contract.contract.Transact(opts, method, params...) +func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ECDSA.Contract.contract.Transact(opts, method, params...) } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeCaller) MAXMESSAGEBODYBYTES(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "MAX_MESSAGE_BODY_BYTES") +// EnumerableSetMetaData contains all meta data concerning the EnumerableSet contract. +var EnumerableSetMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122001368ad527ededa5a6ac32f775715bd9e79d3f2e5933ee0aac3483702713b4c964736f6c634300080d0033", +} - if err != nil { - return *new(*big.Int), err - } +// EnumerableSetABI is the input ABI used to generate the binding from. +// Deprecated: Use EnumerableSetMetaData.ABI instead. +var EnumerableSetABI = EnumerableSetMetaData.ABI - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) +// EnumerableSetBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use EnumerableSetMetaData.Bin instead. +var EnumerableSetBin = EnumerableSetMetaData.Bin - return out0, err +// DeployEnumerableSet deploys a new Ethereum contract, binding an instance of EnumerableSet to it. +func DeployEnumerableSet(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *EnumerableSet, error) { + parsed, err := EnumerableSetMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EnumerableSetBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { - return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) +// EnumerableSet is an auto generated Go binding around an Ethereum contract. +type EnumerableSet struct { + EnumerableSetCaller // Read-only binding to the contract + EnumerableSetTransactor // Write-only binding to the contract + EnumerableSetFilterer // Log filterer for contract events } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeCallerSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { - return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) +// EnumerableSetCaller is an auto generated read-only Go binding around an Ethereum contract. +type EnumerableSetCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeCaller) VERSION(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "VERSION") +// EnumerableSetTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EnumerableSetTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - if err != nil { - return *new(uint8), err - } +// EnumerableSetFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EnumerableSetFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) +// EnumerableSetSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type EnumerableSetSession struct { + Contract *EnumerableSet // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - return out0, err +// EnumerableSetCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type EnumerableSetCallerSession struct { + Contract *EnumerableSetCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} +// EnumerableSetTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type EnumerableSetTransactorSession struct { + Contract *EnumerableSetTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeSession) VERSION() (uint8, error) { - return _Home.Contract.VERSION(&_Home.CallOpts) +// EnumerableSetRaw is an auto generated low-level Go binding around an Ethereum contract. +type EnumerableSetRaw struct { + Contract *EnumerableSet // Generic contract binding to access the raw methods on } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeCallerSession) VERSION() (uint8, error) { - return _Home.Contract.VERSION(&_Home.CallOpts) +// EnumerableSetCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EnumerableSetCallerRaw struct { + Contract *EnumerableSetCaller // Generic read-only contract binding to access the raw methods on } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeCaller) Count(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "count") +// EnumerableSetTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EnumerableSetTransactorRaw struct { + Contract *EnumerableSetTransactor // Generic write-only contract binding to access the raw methods on +} +// NewEnumerableSet creates a new instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSet(address common.Address, backend bind.ContractBackend) (*EnumerableSet, error) { + contract, err := bindEnumerableSet(address, backend, backend, backend) if err != nil { - return *new(*big.Int), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - + return &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeSession) Count() (*big.Int, error) { - return _Home.Contract.Count(&_Home.CallOpts) +// NewEnumerableSetCaller creates a new read-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetCaller(address common.Address, caller bind.ContractCaller) (*EnumerableSetCaller, error) { + contract, err := bindEnumerableSet(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EnumerableSetCaller{contract: contract}, nil } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeCallerSession) Count() (*big.Int, error) { - return _Home.Contract.Count(&_Home.CallOpts) +// NewEnumerableSetTransactor creates a new write-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetTransactor(address common.Address, transactor bind.ContractTransactor) (*EnumerableSetTransactor, error) { + contract, err := bindEnumerableSet(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EnumerableSetTransactor{contract: contract}, nil } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "historicalRoots", arg0) +// NewEnumerableSetFilterer creates a new log filterer instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetFilterer(address common.Address, filterer bind.ContractFilterer) (*EnumerableSetFilterer, error) { + contract, err := bindEnumerableSet(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EnumerableSetFilterer{contract: contract}, nil +} +// bindEnumerableSet binds a generic wrapper to an already deployed contract. +func bindEnumerableSet(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(EnumerableSetABI)) if err != nil { - return *new([32]byte), err + return nil, err } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EnumerableSet *EnumerableSetRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.EnumerableSetCaller.contract.Call(opts, result, method, params...) +} - return out0, err +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EnumerableSet *EnumerableSetRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transfer(opts) +} +// Transact invokes the (paid) contract method with params as input values. +func (_EnumerableSet *EnumerableSetRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transact(opts, method, params...) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EnumerableSet *EnumerableSetCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.contract.Call(opts, result, method, params...) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EnumerableSet *EnumerableSetTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transfer(opts) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "localDomain") +// Transact invokes the (paid) contract method with params as input values. +func (_EnumerableSet *EnumerableSetTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transact(opts, method, params...) +} + +// GuardRegistryMetaData contains all meta data concerning the GuardRegistry contract. +var GuardRegistryMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "9fe03fa2": "allGuards()", + "629ddf69": "getGuard(uint256)", + "246c2449": "guardsAmount()", + }, + Bin: "0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220474cfa44d374c0ec38027aaecbcb0f008ff0a37aa575a9a55a61b9b3339b42f264736f6c634300080d0033", +} + +// GuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use GuardRegistryMetaData.ABI instead. +var GuardRegistryABI = GuardRegistryMetaData.ABI +// Deprecated: Use GuardRegistryMetaData.Sigs instead. +// GuardRegistryFuncSigs maps the 4-byte function signature to its string representation. +var GuardRegistryFuncSigs = GuardRegistryMetaData.Sigs + +// GuardRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GuardRegistryMetaData.Bin instead. +var GuardRegistryBin = GuardRegistryMetaData.Bin + +// DeployGuardRegistry deploys a new Ethereum contract, binding an instance of GuardRegistry to it. +func DeployGuardRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GuardRegistry, error) { + parsed, err := GuardRegistryMetaData.GetAbi() if err != nil { - return *new(uint32), err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GuardRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil +} - return out0, err +// GuardRegistry is an auto generated Go binding around an Ethereum contract. +type GuardRegistry struct { + GuardRegistryCaller // Read-only binding to the contract + GuardRegistryTransactor // Write-only binding to the contract + GuardRegistryFilterer // Log filterer for contract events +} +// GuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type GuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeSession) LocalDomain() (uint32, error) { - return _Home.Contract.LocalDomain(&_Home.CallOpts) +// GuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeCallerSession) LocalDomain() (uint32, error) { - return _Home.Contract.LocalDomain(&_Home.CallOpts) +// GuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeCaller) Nonce(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "nonce") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) +// GuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GuardRegistrySession struct { + Contract *GuardRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - return out0, err +// GuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type GuardRegistryCallerSession struct { + Contract *GuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} +// GuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type GuardRegistryTransactorSession struct { + Contract *GuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeSession) Nonce() (uint32, error) { - return _Home.Contract.Nonce(&_Home.CallOpts) +// GuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type GuardRegistryRaw struct { + Contract *GuardRegistry // Generic contract binding to access the raw methods on } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeCallerSession) Nonce() (uint32, error) { - return _Home.Contract.Nonce(&_Home.CallOpts) +// GuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GuardRegistryCallerRaw struct { + Contract *GuardRegistryCaller // Generic read-only contract binding to access the raw methods on } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "owner") +// GuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GuardRegistryTransactorRaw struct { + Contract *GuardRegistryTransactor // Generic write-only contract binding to access the raw methods on +} +// NewGuardRegistry creates a new instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistry(address common.Address, backend bind.ContractBackend) (*GuardRegistry, error) { + contract, err := bindGuardRegistry(address, backend, backend, backend) if err != nil { - return *new(common.Address), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - + return &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeSession) Owner() (common.Address, error) { - return _Home.Contract.Owner(&_Home.CallOpts) +// NewGuardRegistryCaller creates a new read-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*GuardRegistryCaller, error) { + contract, err := bindGuardRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &GuardRegistryCaller{contract: contract}, nil } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeCallerSession) Owner() (common.Address, error) { - return _Home.Contract.Owner(&_Home.CallOpts) +// NewGuardRegistryTransactor creates a new write-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*GuardRegistryTransactor, error) { + contract, err := bindGuardRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &GuardRegistryTransactor{contract: contract}, nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeCaller) Root(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "root") - +// NewGuardRegistryFilterer creates a new log filterer instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*GuardRegistryFilterer, error) { + contract, err := bindGuardRegistry(address, nil, nil, filterer) if err != nil { - return *new([32]byte), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - + return &GuardRegistryFilterer{contract: contract}, nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeSession) Root() ([32]byte, error) { - return _Home.Contract.Root(&_Home.CallOpts) +// bindGuardRegistry binds a generic wrapper to an already deployed contract. +func bindGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(GuardRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeCallerSession) Root() ([32]byte, error) { - return _Home.Contract.Root(&_Home.CallOpts) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GuardRegistry *GuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.GuardRegistryCaller.contract.Call(opts, result, method, params...) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeCaller) State(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "state") - - if err != nil { - return *new(uint8), err - } - - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GuardRegistry *GuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transfer(opts) +} - return out0, err +// Transact invokes the (paid) contract method with params as input values. +func (_GuardRegistry *GuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transact(opts, method, params...) +} +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GuardRegistry *GuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.contract.Call(opts, result, method, params...) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeSession) State() (uint8, error) { - return _Home.Contract.State(&_Home.CallOpts) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GuardRegistry *GuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transfer(opts) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeCallerSession) State() (uint8, error) { - return _Home.Contract.State(&_Home.CallOpts) +// Transact invokes the (paid) contract method with params as input values. +func (_GuardRegistry *GuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transact(opts, method, params...) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeCaller) SuggestUpdate(opts *bind.CallOpts) (struct { - Nonce uint32 - Root [32]byte -}, error) { +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "suggestUpdate") + err := _GuardRegistry.contract.Call(opts, &out, "allGuards") - outstruct := new(struct { - Nonce uint32 - Root [32]byte - }) if err != nil { - return *outstruct, err + return *new([]common.Address), err } - outstruct.Nonce = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - return *outstruct, err + return out0, err } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeSession) SuggestUpdate() (struct { - Nonce uint32 - Root [32]byte -}, error) { - return _Home.Contract.SuggestUpdate(&_Home.CallOpts) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistrySession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeCallerSession) SuggestUpdate() (struct { - Nonce uint32 - Root [32]byte -}, error) { - return _Home.Contract.SuggestUpdate(&_Home.CallOpts) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCallerSession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "systemMessenger") + err := _GuardRegistry.contract.Call(opts, &out, "getGuard", _index) if err != nil { return *new(common.Address), err @@ -2044,26 +2426,26 @@ func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, e } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeSession) SystemMessenger() (common.Address, error) { - return _Home.Contract.SystemMessenger(&_Home.CallOpts) +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistrySession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeCallerSession) SystemMessenger() (common.Address, error) { - return _Home.Contract.SystemMessenger(&_Home.CallOpts) +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "tree") + err := _GuardRegistry.contract.Call(opts, &out, "guardsAmount") if err != nil { return *new(*big.Int), err @@ -2075,253 +2457,157 @@ func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeSession) Tree() (*big.Int, error) { - return _Home.Contract.Tree(&_Home.CallOpts) +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistrySession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeCallerSession) Tree() (*big.Int, error) { - return _Home.Contract.Tree(&_Home.CallOpts) +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCallerSession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "updater") +// GuardRegistryGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the GuardRegistry contract. +type GuardRegistryGuardAddedIterator struct { + Event *GuardRegistryGuardAdded // Event containing the contract specifics and raw log - if err != nil { - return *new(common.Address), err + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GuardRegistryGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - return out0, err + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GuardRegistryGuardAddedIterator) Error() error { + return it.fail } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeSession) Updater() (common.Address, error) { - return _Home.Contract.Updater(&_Home.CallOpts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardRegistryGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeCallerSession) Updater() (common.Address, error) { - return _Home.Contract.Updater(&_Home.CallOpts) +// GuardRegistryGuardAdded represents a GuardAdded event raised by the GuardRegistry contract. +type GuardRegistryGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeCaller) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "updaterManager") +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*GuardRegistryGuardAddedIterator, error) { + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardAdded") if err != nil { - return *new(common.Address), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - + return &GuardRegistryGuardAddedIterator{contract: _GuardRegistry.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeSession) UpdaterManager() (common.Address, error) { - return _Home.Contract.UpdaterManager(&_Home.CallOpts) -} - -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. -// -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeCallerSession) UpdaterManager() (common.Address, error) { - return _Home.Contract.UpdaterManager(&_Home.CallOpts) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeTransactor) Dispatch(opts *bind.TransactOpts, _destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "dispatch", _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeTransactorSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeTransactor) ImproperAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "improperAttestation", _attestation) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { - return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeTransactorSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { - return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeTransactor) Initialize(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "initialize", _updaterManager) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeTransactorSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeSession) RenounceOwnership() (*types.Transaction, error) { - return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setSystemMessenger", _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setUpdater", _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeTransactor) SetUpdaterManager(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setUpdaterManager", _updaterManager) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeTransactorSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) -} +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardAdded) (event.Subscription, error) { -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "transferOwnership", newOwner) -} + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardAdded(log types.Log) (*GuardRegistryGuardAdded, error) { + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// HomeDispatchIterator is returned from FilterDispatch and is used to iterate over the raw logs and unpacked data for Dispatch events raised by the Home contract. -type HomeDispatchIterator struct { - Event *HomeDispatch // Event containing the contract specifics and raw log +// GuardRegistryGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the GuardRegistry contract. +type GuardRegistryGuardRemovedIterator struct { + Event *GuardRegistryGuardRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2335,7 +2621,7 @@ type HomeDispatchIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeDispatchIterator) Next() bool { +func (it *GuardRegistryGuardRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2344,7 +2630,7 @@ func (it *HomeDispatchIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeDispatch) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2359,7 +2645,7 @@ func (it *HomeDispatchIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeDispatch) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2375,71 +2661,41 @@ func (it *HomeDispatchIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeDispatchIterator) Error() error { +func (it *GuardRegistryGuardRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeDispatchIterator) Close() error { +func (it *GuardRegistryGuardRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeDispatch represents a Dispatch event raised by the Home contract. -type HomeDispatch struct { - MessageHash [32]byte - LeafIndex *big.Int - DestinationAndNonce uint64 - Tips []byte - Message []byte - Raw types.Log // Blockchain specific contextual infos +// GuardRegistryGuardRemoved represents a GuardRemoved event raised by the GuardRegistry contract. +type GuardRegistryGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterDispatch is a free log retrieval operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (*HomeDispatchIterator, error) { - - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) - } - var leafIndexRule []interface{} - for _, leafIndexItem := range leafIndex { - leafIndexRule = append(leafIndexRule, leafIndexItem) - } - var destinationAndNonceRule []interface{} - for _, destinationAndNonceItem := range destinationAndNonce { - destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) - } +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*GuardRegistryGuardRemovedIterator, error) { - logs, sub, err := _Home.contract.FilterLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardRemoved") if err != nil { return nil, err } - return &HomeDispatchIterator{contract: _Home.contract, event: "Dispatch", logs: logs, sub: sub}, nil + return &GuardRegistryGuardRemovedIterator{contract: _GuardRegistry.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil } -// WatchDispatch is a free log subscription operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *HomeDispatch, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (event.Subscription, error) { - - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) - } - var leafIndexRule []interface{} - for _, leafIndexItem := range leafIndex { - leafIndexRule = append(leafIndexRule, leafIndexItem) - } - var destinationAndNonceRule []interface{} - for _, destinationAndNonceItem := range destinationAndNonce { - destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) - } +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardRemoved) (event.Subscription, error) { - logs, sub, err := _Home.contract.WatchLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardRemoved") if err != nil { return nil, err } @@ -2449,8 +2705,8 @@ func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *Home select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeDispatch) - if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return err } event.Raw = log @@ -2471,390 +2727,1836 @@ func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *Home }), nil } -// ParseDispatch is a log parse operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) ParseDispatch(log types.Log) (*HomeDispatch, error) { - event := new(HomeDispatch) - if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardRemoved(log types.Log) (*GuardRegistryGuardRemoved, error) { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeImproperAttestationIterator is returned from FilterImproperAttestation and is used to iterate over the raw logs and unpacked data for ImproperAttestation events raised by the Home contract. -type HomeImproperAttestationIterator struct { - Event *HomeImproperAttestation // Event containing the contract specifics and raw log +// HeaderMetaData contains all meta data concerning the Header contract. +var HeaderMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122021d5f30e948fc5f90cf8579074c0159128bc49f9984434488c3483606aaf88d164736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// HeaderABI is the input ABI used to generate the binding from. +// Deprecated: Use HeaderMetaData.ABI instead. +var HeaderABI = HeaderMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// HeaderBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HeaderMetaData.Bin instead. +var HeaderBin = HeaderMetaData.Bin -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeImproperAttestationIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. +func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { + parsed, err := HeaderMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeImproperAttestation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeImproperAttestation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } + return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeImproperAttestationIterator) Error() error { - return it.fail +// Header is an auto generated Go binding around an Ethereum contract. +type Header struct { + HeaderCaller // Read-only binding to the contract + HeaderTransactor // Write-only binding to the contract + HeaderFilterer // Log filterer for contract events } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeImproperAttestationIterator) Close() error { - it.sub.Unsubscribe() - return nil +// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. +type HeaderCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeImproperAttestation represents a ImproperAttestation event raised by the Home contract. -type HomeImproperAttestation struct { - Updater common.Address - Attestation []byte - Raw types.Log // Blockchain specific contextual infos +// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HeaderTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) FilterImproperAttestation(opts *bind.FilterOpts) (*HomeImproperAttestationIterator, error) { +// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HeaderFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs, sub, err := _Home.contract.FilterLogs(opts, "ImproperAttestation") +// HeaderSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type HeaderSession struct { + Contract *Header // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type HeaderCallerSession struct { + Contract *HeaderCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type HeaderTransactorSession struct { + Contract *HeaderTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. +type HeaderRaw struct { + Contract *Header // Generic contract binding to access the raw methods on +} + +// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HeaderCallerRaw struct { + Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on +} + +// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HeaderTransactorRaw struct { + Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewHeader creates a new instance of Header, bound to a specific deployed contract. +func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { + contract, err := bindHeader(address, backend, backend, backend) if err != nil { return nil, err } - return &HomeImproperAttestationIterator{contract: _Home.contract, event: "ImproperAttestation", logs: logs, sub: sub}, nil + return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// WatchImproperAttestation is a free log subscription operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *HomeImproperAttestation) (event.Subscription, error) { - - logs, sub, err := _Home.contract.WatchLogs(opts, "ImproperAttestation") +// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. +func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { + contract, err := bindHeader(address, caller, nil, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeImproperAttestation) - if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { - return err - } - event.Raw = log + return &HeaderCaller{contract: contract}, nil +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. +func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { + contract, err := bindHeader(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &HeaderTransactor{contract: contract}, nil } -// ParseImproperAttestation is a log parse operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) ParseImproperAttestation(log types.Log) (*HomeImproperAttestation, error) { - event := new(HomeImproperAttestation) - if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { +// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. +func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { + contract, err := bindHeader(address, nil, nil, filterer) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &HeaderFilterer{contract: contract}, nil } -// HomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Home contract. -type HomeInitializedIterator struct { - Event *HomeInitialized // Event containing the contract specifics and raw log +// bindHeader binds a generic wrapper to an already deployed contract. +func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HeaderABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transfer(opts) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transact invokes the (paid) contract method with params as input values. +func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.contract.Call(opts, result, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeInitializedIterator) Error() error { - return it.fail +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.contract.Transfer(opts) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transact invokes the (paid) contract method with params as input values. +func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.contract.Transact(opts, method, params...) } -// HomeInitialized represents a Initialized event raised by the Home contract. -type HomeInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// HomeMetaData contains all meta data concerning the Home contract. +var HomeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enumHome.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "522ae002": "MAX_MESSAGE_BODY_BYTES()", + "ffa1ad74": "VERSION()", + "9fe03fa2": "allGuards()", + "9817e315": "allNotaries()", + "06661abd": "count()", + "f7560e40": "dispatch(uint32,bytes32,uint32,bytes,bytes)", + "629ddf69": "getGuard(uint256)", + "c07dc7f5": "getNotary(uint256)", + "246c2449": "guardsAmount()", + "7ea97f40": "historicalRoots(uint256)", + "0afe7f90": "improperAttestation(bytes)", + "c4d66de8": "initialize(address)", + "8d3638f4": "localDomain()", + "affed0e0": "nonce()", + "8e62e9ef": "notariesAmount()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "ebf0c717": "root()", + "b7bc563e": "setSystemMessenger(address)", + "9d54f419": "setUpdater(address)", + "9776120e": "setUpdaterManager(address)", + "c19d93fb": "state()", + "36e104de": "suggestUpdate()", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + "fd54b228": "tree()", + "9df6c8e1": "updaterManager()", + }, + Bin: "0x60c06040523480156200001157600080fd5b50604051620038c7380380620038c7833981016040819052620000349162000048565b63ffffffff16608081905260a05262000077565b6000602082840312156200005b57600080fd5b815163ffffffff811681146200007057600080fd5b9392505050565b60805160a051613823620000a460003960006118a70152600081816102ef0152610ea501526138236000f3fe6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea2646970667358221220f4ec54b2d176fcf05d50423158ec4b3391eae01e44861c6f3c163df8aba5512664736f6c634300080d0033", } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*HomeInitializedIterator, error) { +// HomeABI is the input ABI used to generate the binding from. +// Deprecated: Use HomeMetaData.ABI instead. +var HomeABI = HomeMetaData.ABI - logs, sub, err := _Home.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return &HomeInitializedIterator{contract: _Home.contract, event: "Initialized", logs: logs, sub: sub}, nil -} +// Deprecated: Use HomeMetaData.Sigs instead. +// HomeFuncSigs maps the 4-byte function signature to its string representation. +var HomeFuncSigs = HomeMetaData.Sigs -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *HomeInitialized) (event.Subscription, error) { +// HomeBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HomeMetaData.Bin instead. +var HomeBin = HomeMetaData.Bin - logs, sub, err := _Home.contract.WatchLogs(opts, "Initialized") +// DeployHome deploys a new Ethereum contract, binding an instance of Home to it. +func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *Home, error) { + parsed, err := HomeMetaData.GetAbi() if err != nil { - return nil, err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeInitialized) - if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HomeBin), backend, _localDomain) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) ParseInitialized(log types.Log) (*HomeInitialized, error) { - event := new(HomeInitialized) - if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Home is an auto generated Go binding around an Ethereum contract. +type Home struct { + HomeCaller // Read-only binding to the contract + HomeTransactor // Write-only binding to the contract + HomeFilterer // Log filterer for contract events } -// HomeNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the Home contract. -type HomeNewUpdaterIterator struct { - Event *HomeNewUpdater // Event containing the contract specifics and raw log +// HomeCaller is an auto generated read-only Go binding around an Ethereum contract. +type HomeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// HomeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HomeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// HomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HomeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// HomeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type HomeSession struct { + Contract *Home // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// HomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type HomeCallerSession struct { + Contract *HomeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// HomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type HomeTransactorSession struct { + Contract *HomeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeNewUpdaterIterator) Error() error { - return it.fail +// HomeRaw is an auto generated low-level Go binding around an Ethereum contract. +type HomeRaw struct { + Contract *Home // Generic contract binding to access the raw methods on } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// HomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HomeCallerRaw struct { + Contract *HomeCaller // Generic read-only contract binding to access the raw methods on } -// HomeNewUpdater represents a NewUpdater event raised by the Home contract. -type HomeNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// HomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HomeTransactorRaw struct { + Contract *HomeTransactor // Generic write-only contract binding to access the raw methods on } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*HomeNewUpdaterIterator, error) { +// NewHome creates a new instance of Home, bound to a specific deployed contract. +func NewHome(address common.Address, backend bind.ContractBackend) (*Home, error) { + contract, err := bindHome(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil +} - logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdater") +// NewHomeCaller creates a new read-only instance of Home, bound to a specific deployed contract. +func NewHomeCaller(address common.Address, caller bind.ContractCaller) (*HomeCaller, error) { + contract, err := bindHome(address, caller, nil, nil) if err != nil { return nil, err } - return &HomeNewUpdaterIterator{contract: _Home.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &HomeCaller{contract: contract}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *HomeNewUpdater) (event.Subscription, error) { +// NewHomeTransactor creates a new write-only instance of Home, bound to a specific deployed contract. +func NewHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*HomeTransactor, error) { + contract, err := bindHome(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &HomeTransactor{contract: contract}, nil +} - logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdater") +// NewHomeFilterer creates a new log filterer instance of Home, bound to a specific deployed contract. +func NewHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*HomeFilterer, error) { + contract, err := bindHome(address, nil, nil, filterer) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() + return &HomeFilterer{contract: contract}, nil +} + +// bindHome binds a generic wrapper to an already deployed contract. +func bindHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HomeABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Home *HomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Home.Contract.HomeCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Home *HomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.Contract.HomeTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Home *HomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Home.Contract.HomeTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Home *HomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Home.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Home *HomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Home *HomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Home.Contract.contract.Transact(opts, method, params...) +} + +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeCaller) MAXMESSAGEBODYBYTES(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "MAX_MESSAGE_BODY_BYTES") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { + return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) +} + +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeCallerSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { + return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeCaller) VERSION(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "VERSION") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeSession) VERSION() (uint8, error) { + return _Home.Contract.VERSION(&_Home.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeCallerSession) VERSION() (uint8, error) { + return _Home.Contract.VERSION(&_Home.CallOpts) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "allGuards") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeSession) AllGuards() ([]common.Address, error) { + return _Home.Contract.AllGuards(&_Home.CallOpts) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeCallerSession) AllGuards() ([]common.Address, error) { + return _Home.Contract.AllGuards(&_Home.CallOpts) +} + +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeCaller) AllNotaries(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "allNotaries") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeSession) AllNotaries() ([]common.Address, error) { + return _Home.Contract.AllNotaries(&_Home.CallOpts) +} + +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeCallerSession) AllNotaries() ([]common.Address, error) { + return _Home.Contract.AllNotaries(&_Home.CallOpts) +} + +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_Home *HomeCaller) Count(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "count") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_Home *HomeSession) Count() (*big.Int, error) { + return _Home.Contract.Count(&_Home.CallOpts) +} + +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_Home *HomeCallerSession) Count() (*big.Int, error) { + return _Home.Contract.Count(&_Home.CallOpts) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "getGuard", _index) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeSession) GetGuard(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetGuard(&_Home.CallOpts, _index) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetGuard(&_Home.CallOpts, _index) +} + +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeCaller) GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "getNotary", _index) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeSession) GetNotary(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetNotary(&_Home.CallOpts, _index) +} + +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeCallerSession) GetNotary(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetNotary(&_Home.CallOpts, _index) +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "guardsAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeSession) GuardsAmount() (*big.Int, error) { + return _Home.Contract.GuardsAmount(&_Home.CallOpts) +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeCallerSession) GuardsAmount() (*big.Int, error) { + return _Home.Contract.GuardsAmount(&_Home.CallOpts) +} + +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "historicalRoots", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +} + +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeSession) LocalDomain() (uint32, error) { + return _Home.Contract.LocalDomain(&_Home.CallOpts) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeCallerSession) LocalDomain() (uint32, error) { + return _Home.Contract.LocalDomain(&_Home.CallOpts) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeCaller) Nonce(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "nonce") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeSession) Nonce() (uint32, error) { + return _Home.Contract.Nonce(&_Home.CallOpts) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeCallerSession) Nonce() (uint32, error) { + return _Home.Contract.Nonce(&_Home.CallOpts) +} + +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeCaller) NotariesAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "notariesAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeSession) NotariesAmount() (*big.Int, error) { + return _Home.Contract.NotariesAmount(&_Home.CallOpts) +} + +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeCallerSession) NotariesAmount() (*big.Int, error) { + return _Home.Contract.NotariesAmount(&_Home.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeSession) Owner() (common.Address, error) { + return _Home.Contract.Owner(&_Home.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeCallerSession) Owner() (common.Address, error) { + return _Home.Contract.Owner(&_Home.CallOpts) +} + +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeCaller) Root(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "root") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeSession) Root() ([32]byte, error) { + return _Home.Contract.Root(&_Home.CallOpts) +} + +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeCallerSession) Root() ([32]byte, error) { + return _Home.Contract.Root(&_Home.CallOpts) +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeCaller) State(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "state") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeSession) State() (uint8, error) { + return _Home.Contract.State(&_Home.CallOpts) +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeCallerSession) State() (uint8, error) { + return _Home.Contract.State(&_Home.CallOpts) +} + +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeCaller) SuggestUpdate(opts *bind.CallOpts) (struct { + Nonce uint32 + Root [32]byte +}, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "suggestUpdate") + + outstruct := new(struct { + Nonce uint32 + Root [32]byte + }) + if err != nil { + return *outstruct, err + } + + outstruct.Nonce = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeSession) SuggestUpdate() (struct { + Nonce uint32 + Root [32]byte +}, error) { + return _Home.Contract.SuggestUpdate(&_Home.CallOpts) +} + +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeCallerSession) SuggestUpdate() (struct { + Nonce uint32 + Root [32]byte +}, error) { + return _Home.Contract.SuggestUpdate(&_Home.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "systemMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeSession) SystemMessenger() (common.Address, error) { + return _Home.Contract.SystemMessenger(&_Home.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeCallerSession) SystemMessenger() (common.Address, error) { + return _Home.Contract.SystemMessenger(&_Home.CallOpts) +} + +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "tree") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeSession) Tree() (*big.Int, error) { + return _Home.Contract.Tree(&_Home.CallOpts) +} + +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeCallerSession) Tree() (*big.Int, error) { + return _Home.Contract.Tree(&_Home.CallOpts) +} + +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeCaller) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "updaterManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeSession) UpdaterManager() (common.Address, error) { + return _Home.Contract.UpdaterManager(&_Home.CallOpts) +} + +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeCallerSession) UpdaterManager() (common.Address, error) { + return _Home.Contract.UpdaterManager(&_Home.CallOpts) +} + +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeTransactor) Dispatch(opts *bind.TransactOpts, _destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "dispatch", _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) +} + +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) +} + +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeTransactorSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) +} + +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeTransactor) ImproperAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "improperAttestation", _attestation) +} + +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { + return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) +} + +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeTransactorSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { + return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeTransactor) Initialize(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "initialize", _updaterManager) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeTransactorSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Home *HomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Home *HomeSession) RenounceOwnership() (*types.Transaction, error) { + return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Home *HomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setUpdater", _updater) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) +} + +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeTransactor) SetUpdaterManager(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setUpdaterManager", _updaterManager) +} + +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) +} + +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeTransactorSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) +} + +// HomeDispatchIterator is returned from FilterDispatch and is used to iterate over the raw logs and unpacked data for Dispatch events raised by the Home contract. +type HomeDispatchIterator struct { + Event *HomeDispatch // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeDispatchIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeDispatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeDispatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeDispatchIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeDispatchIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeDispatch represents a Dispatch event raised by the Home contract. +type HomeDispatch struct { + MessageHash [32]byte + LeafIndex *big.Int + DestinationAndNonce uint64 + Tips []byte + Message []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDispatch is a free log retrieval operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (*HomeDispatchIterator, error) { + + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) + } + var leafIndexRule []interface{} + for _, leafIndexItem := range leafIndex { + leafIndexRule = append(leafIndexRule, leafIndexItem) + } + var destinationAndNonceRule []interface{} + for _, destinationAndNonceItem := range destinationAndNonce { + destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) + } + + logs, sub, err := _Home.contract.FilterLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + if err != nil { + return nil, err + } + return &HomeDispatchIterator{contract: _Home.contract, event: "Dispatch", logs: logs, sub: sub}, nil +} + +// WatchDispatch is a free log subscription operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *HomeDispatch, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (event.Subscription, error) { + + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) + } + var leafIndexRule []interface{} + for _, leafIndexItem := range leafIndex { + leafIndexRule = append(leafIndexRule, leafIndexItem) + } + var destinationAndNonceRule []interface{} + for _, destinationAndNonceItem := range destinationAndNonce { + destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) + } + + logs, sub, err := _Home.contract.WatchLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeDispatch) + if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDispatch is a log parse operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) ParseDispatch(log types.Log) (*HomeDispatch, error) { + event := new(HomeDispatch) + if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeDomainNotaryAddedIterator is returned from FilterDomainNotaryAdded and is used to iterate over the raw logs and unpacked data for DomainNotaryAdded events raised by the Home contract. +type HomeDomainNotaryAddedIterator struct { + Event *HomeDomainNotaryAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeDomainNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeDomainNotaryAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeDomainNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeDomainNotaryAdded represents a DomainNotaryAdded event raised by the Home contract. +type HomeDomainNotaryAdded struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDomainNotaryAdded is a free log retrieval operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) FilterDomainNotaryAdded(opts *bind.FilterOpts) (*HomeDomainNotaryAddedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "DomainNotaryAdded") + if err != nil { + return nil, err + } + return &HomeDomainNotaryAddedIterator{contract: _Home.contract, event: "DomainNotaryAdded", logs: logs, sub: sub}, nil +} + +// WatchDomainNotaryAdded is a free log subscription operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *HomeDomainNotaryAdded) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "DomainNotaryAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeDomainNotaryAdded) + if err := _Home.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDomainNotaryAdded is a log parse operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) ParseDomainNotaryAdded(log types.Log) (*HomeDomainNotaryAdded, error) { + event := new(HomeDomainNotaryAdded) + if err := _Home.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeDomainNotaryRemovedIterator is returned from FilterDomainNotaryRemoved and is used to iterate over the raw logs and unpacked data for DomainNotaryRemoved events raised by the Home contract. +type HomeDomainNotaryRemovedIterator struct { + Event *HomeDomainNotaryRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeDomainNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeDomainNotaryRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeDomainNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeDomainNotaryRemoved represents a DomainNotaryRemoved event raised by the Home contract. +type HomeDomainNotaryRemoved struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDomainNotaryRemoved is a free log retrieval operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*HomeDomainNotaryRemovedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return &HomeDomainNotaryRemovedIterator{contract: _Home.contract, event: "DomainNotaryRemoved", logs: logs, sub: sub}, nil +} + +// WatchDomainNotaryRemoved is a free log subscription operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *HomeDomainNotaryRemoved) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeDomainNotaryRemoved) + if err := _Home.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDomainNotaryRemoved is a log parse operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) ParseDomainNotaryRemoved(log types.Log) (*HomeDomainNotaryRemoved, error) { + event := new(HomeDomainNotaryRemoved) + if err := _Home.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the Home contract. +type HomeGuardAddedIterator struct { + Event *HomeGuardAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeGuardAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeGuardAdded represents a GuardAdded event raised by the Home contract. +type HomeGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*HomeGuardAddedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return &HomeGuardAddedIterator{contract: _Home.contract, event: "GuardAdded", logs: logs, sub: sub}, nil +} + +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *HomeGuardAdded) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeGuardAdded) + if err := _Home.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) ParseGuardAdded(log types.Log) (*HomeGuardAdded, error) { + event := new(HomeGuardAdded) + if err := _Home.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the Home contract. +type HomeGuardRemovedIterator struct { + Event *HomeGuardRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeGuardRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeGuardRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeGuardRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeGuardRemoved represents a GuardRemoved event raised by the Home contract. +type HomeGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*HomeGuardRemovedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return &HomeGuardRemovedIterator{contract: _Home.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil +} + +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *HomeGuardRemoved) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() for { select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeNewUpdater) - if err := _Home.contract.UnpackLog(event, "NewUpdater", log); err != nil { + event := new(HomeGuardRemoved) + if err := _Home.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return err } event.Raw = log @@ -2875,21 +4577,21 @@ func (_Home *HomeFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *Ho }), nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) ParseNewUpdater(log types.Log) (*HomeNewUpdater, error) { - event := new(HomeNewUpdater) - if err := _Home.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) ParseGuardRemoved(log types.Log) (*HomeGuardRemoved, error) { + event := new(HomeGuardRemoved) + if err := _Home.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeNewUpdaterManagerIterator is returned from FilterNewUpdaterManager and is used to iterate over the raw logs and unpacked data for NewUpdaterManager events raised by the Home contract. -type HomeNewUpdaterManagerIterator struct { - Event *HomeNewUpdaterManager // Event containing the contract specifics and raw log +// HomeImproperAttestationIterator is returned from FilterImproperAttestation and is used to iterate over the raw logs and unpacked data for ImproperAttestation events raised by the Home contract. +type HomeImproperAttestationIterator struct { + Event *HomeImproperAttestation // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2903,7 +4605,7 @@ type HomeNewUpdaterManagerIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeNewUpdaterManagerIterator) Next() bool { +func (it *HomeImproperAttestationIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2912,7 +4614,7 @@ func (it *HomeNewUpdaterManagerIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeNewUpdaterManager) + it.Event = new(HomeImproperAttestation) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2927,7 +4629,7 @@ func (it *HomeNewUpdaterManagerIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeNewUpdaterManager) + it.Event = new(HomeImproperAttestation) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2943,41 +4645,42 @@ func (it *HomeNewUpdaterManagerIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeNewUpdaterManagerIterator) Error() error { +func (it *HomeImproperAttestationIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeNewUpdaterManagerIterator) Close() error { +func (it *HomeImproperAttestationIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeNewUpdaterManager represents a NewUpdaterManager event raised by the Home contract. -type HomeNewUpdaterManager struct { - UpdaterManager common.Address - Raw types.Log // Blockchain specific contextual infos +// HomeImproperAttestation represents a ImproperAttestation event raised by the Home contract. +type HomeImproperAttestation struct { + Updater common.Address + Attestation []byte + Raw types.Log // Blockchain specific contextual infos } -// FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) FilterNewUpdaterManager(opts *bind.FilterOpts) (*HomeNewUpdaterManagerIterator, error) { +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) FilterImproperAttestation(opts *bind.FilterOpts) (*HomeImproperAttestationIterator, error) { - logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdaterManager") + logs, sub, err := _Home.contract.FilterLogs(opts, "ImproperAttestation") if err != nil { return nil, err } - return &HomeNewUpdaterManagerIterator{contract: _Home.contract, event: "NewUpdaterManager", logs: logs, sub: sub}, nil + return &HomeImproperAttestationIterator{contract: _Home.contract, event: "ImproperAttestation", logs: logs, sub: sub}, nil } -// WatchNewUpdaterManager is a free log subscription operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// WatchImproperAttestation is a free log subscription operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *HomeNewUpdaterManager) (event.Subscription, error) { +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *HomeImproperAttestation) (event.Subscription, error) { - logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdaterManager") + logs, sub, err := _Home.contract.WatchLogs(opts, "ImproperAttestation") if err != nil { return nil, err } @@ -2987,8 +4690,8 @@ func (_Home *HomeFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink cha select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeNewUpdaterManager) - if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { + event := new(HomeImproperAttestation) + if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { return err } event.Raw = log @@ -3009,21 +4712,21 @@ func (_Home *HomeFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink cha }), nil } -// ParseNewUpdaterManager is a log parse operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// ParseImproperAttestation is a log parse operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) ParseNewUpdaterManager(log types.Log) (*HomeNewUpdaterManager, error) { - event := new(HomeNewUpdaterManager) - if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) ParseImproperAttestation(log types.Log) (*HomeImproperAttestation, error) { + event := new(HomeImproperAttestation) + if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Home contract. -type HomeOwnershipTransferredIterator struct { - Event *HomeOwnershipTransferred // Event containing the contract specifics and raw log +// HomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Home contract. +type HomeInitializedIterator struct { + Event *HomeInitialized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -3037,7 +4740,7 @@ type HomeOwnershipTransferredIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeOwnershipTransferredIterator) Next() bool { +func (it *HomeInitializedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -3046,7 +4749,7 @@ func (it *HomeOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeOwnershipTransferred) + it.Event = new(HomeInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3061,7 +4764,7 @@ func (it *HomeOwnershipTransferredIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeOwnershipTransferred) + it.Event = new(HomeInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3077,60 +4780,175 @@ func (it *HomeOwnershipTransferredIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeOwnershipTransferredIterator) Error() error { +func (it *HomeInitializedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeOwnershipTransferredIterator) Close() error { +func (it *HomeInitializedIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeOwnershipTransferred represents a OwnershipTransferred event raised by the Home contract. -type HomeOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// HomeInitialized represents a Initialized event raised by the Home contract. +type HomeInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*HomeOwnershipTransferredIterator, error) { +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*HomeInitializedIterator, error) { - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + logs, sub, err := _Home.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) + return &HomeInitializedIterator{contract: _Home.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *HomeInitialized) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeInitialized) + if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log - logs, sub, err := _Home.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) ParseInitialized(log types.Log) (*HomeInitialized, error) { + event := new(HomeInitialized) + if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeNewUpdaterManagerIterator is returned from FilterNewUpdaterManager and is used to iterate over the raw logs and unpacked data for NewUpdaterManager events raised by the Home contract. +type HomeNewUpdaterManagerIterator struct { + Event *HomeNewUpdaterManager // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeNewUpdaterManagerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeNewUpdaterManager) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeNewUpdaterManager) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeNewUpdaterManagerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeNewUpdaterManagerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeNewUpdaterManager represents a NewUpdaterManager event raised by the Home contract. +type HomeNewUpdaterManager struct { + UpdaterManager common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) FilterNewUpdaterManager(opts *bind.FilterOpts) (*HomeNewUpdaterManagerIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdaterManager") if err != nil { return nil, err } - return &HomeOwnershipTransferredIterator{contract: _Home.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &HomeNewUpdaterManagerIterator{contract: _Home.contract, event: "NewUpdaterManager", logs: logs, sub: sub}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// WatchNewUpdaterManager is a free log subscription operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *HomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *HomeNewUpdaterManager) (event.Subscription, error) { - logs, sub, err := _Home.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdaterManager") if err != nil { return nil, err } @@ -3140,8 +4958,8 @@ func (_Home *HomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeOwnershipTransferred) - if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(HomeNewUpdaterManager) + if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { return err } event.Raw = log @@ -3162,21 +4980,21 @@ func (_Home *HomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink }), nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// ParseNewUpdaterManager is a log parse operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) ParseOwnershipTransferred(log types.Log) (*HomeOwnershipTransferred, error) { - event := new(HomeOwnershipTransferred) - if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) ParseNewUpdaterManager(log types.Log) (*HomeNewUpdaterManager, error) { + event := new(HomeNewUpdaterManager) + if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the Home contract. -type HomeUpdateIterator struct { - Event *HomeUpdate // Event containing the contract specifics and raw log +// HomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Home contract. +type HomeOwnershipTransferredIterator struct { + Event *HomeOwnershipTransferred // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -3190,7 +5008,7 @@ type HomeUpdateIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeUpdateIterator) Next() bool { +func (it *HomeOwnershipTransferredIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -3199,7 +5017,7 @@ func (it *HomeUpdateIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeUpdate) + it.Event = new(HomeOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3214,7 +5032,7 @@ func (it *HomeUpdateIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeUpdate) + it.Event = new(HomeOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3230,70 +5048,60 @@ func (it *HomeUpdateIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeUpdateIterator) Error() error { +func (it *HomeOwnershipTransferredIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeUpdateIterator) Close() error { +func (it *HomeOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeUpdate represents a Update event raised by the Home contract. -type HomeUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// HomeOwnershipTransferred represents a OwnershipTransferred event raised by the Home contract. +type HomeOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*HomeUpdateIterator, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*HomeOwnershipTransferredIterator, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _Home.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _Home.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } - return &HomeUpdateIterator{contract: _Home.contract, event: "Update", logs: logs, sub: sub}, nil + return &HomeOwnershipTransferredIterator{contract: _Home.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *HomeUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *HomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _Home.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _Home.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } @@ -3303,8 +5111,8 @@ func (_Home *HomeFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *HomeUp select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeUpdate) - if err := _Home.contract.UnpackLog(event, "Update", log); err != nil { + event := new(HomeOwnershipTransferred) + if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -3325,12 +5133,12 @@ func (_Home *HomeFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *HomeUp }), nil } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) ParseUpdate(log types.Log) (*HomeUpdate, error) { - event := new(HomeUpdate) - if err := _Home.contract.UnpackLog(event, "Update", log); err != nil { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) ParseOwnershipTransferred(log types.Log) (*HomeOwnershipTransferred, error) { + event := new(HomeOwnershipTransferred) + if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log @@ -4168,7 +5976,7 @@ func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*I // MerkleLibMetaData contains all meta data concerning the MerkleLib contract. var MerkleLibMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b737e947247f0f89898c3566b3afaad49da119f05331b4bec3e9032c64970f3264736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122032c981b40e98c6518e9b184e27c95fe99a3d7098e53f36ff2dacd94c9bd8c72c64736f6c634300080d0033", } // MerkleLibABI is the input ABI used to generate the binding from. @@ -4347,7 +6155,7 @@ var MerkleTreeManagerMetaData = &bind.MetaData{ "ebf0c717": "root()", "fd54b228": "tree()", }, - Bin: "0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207896510a8d1ce75be68644ea5051254561e0e79b05bc30e55cbe0222d59335a164736f6c634300080d0033", + Bin: "0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122032e9d16aee7ef1e1ea01a3a3f1c5c0af291445a23dac856da5f1d026ea9f88ee64736f6c634300080d0033", } // MerkleTreeManagerABI is the input ABI used to generate the binding from. @@ -4648,7 +6456,7 @@ func (_MerkleTreeManager *MerkleTreeManagerCallerSession) Tree() (*big.Int, erro // MessageMetaData contains all meta data concerning the Message contract. var MessageMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ac66f819cd7f6b8f15774cd2f663f8d36a1e3c457c46e5f44363c1711e30dda364736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507ff668f5b5f6099edd5845f8951dd7eaca2b6193823343e3386d623462731f64736f6c634300080d0033", } // MessageABI is the input ABI used to generate the binding from. @@ -5341,7 +7149,7 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred // StringsMetaData contains all meta data concerning the Strings contract. var StringsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220958f158d4121a9ee7472bf1af1ba99d418ed03bdad597d5eeeb22ead10fd1ad064736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208d0b12f0092953f7cabf5de746cbb5ee40d542852e361f4b715f3bb6c7a951a664736f6c634300080d0033", } // StringsABI is the input ABI used to generate the binding from. @@ -5511,308 +7319,125 @@ func (_Strings *StringsTransactorRaw) Transact(opts *bind.TransactOpts, method s return _Strings.Contract.contract.Transact(opts, method, params...) } -// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. -var SystemMessageMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212203f6845479810340a467d2cde8987224b4b6c2285b5a69de39862e19c7cf8319064736f6c634300080d0033", -} - -// SystemMessageABI is the input ABI used to generate the binding from. -// Deprecated: Use SystemMessageMetaData.ABI instead. -var SystemMessageABI = SystemMessageMetaData.ABI - -// SystemMessageBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use SystemMessageMetaData.Bin instead. -var SystemMessageBin = SystemMessageMetaData.Bin - -// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. -func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { - parsed, err := SystemMessageMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil -} - -// SystemMessage is an auto generated Go binding around an Ethereum contract. -type SystemMessage struct { - SystemMessageCaller // Read-only binding to the contract - SystemMessageTransactor // Write-only binding to the contract - SystemMessageFilterer // Log filterer for contract events -} - -// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. -type SystemMessageCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type SystemMessageTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type SystemMessageFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type SystemMessageSession struct { - Contract *SystemMessage // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type SystemMessageCallerSession struct { - Contract *SystemMessageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type SystemMessageTransactorSession struct { - Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. -type SystemMessageRaw struct { - Contract *SystemMessage // Generic contract binding to access the raw methods on -} - -// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type SystemMessageCallerRaw struct { - Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on -} - -// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type SystemMessageTransactorRaw struct { - Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { - contract, err := bindSystemMessage(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil -} - -// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { - contract, err := bindSystemMessage(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &SystemMessageCaller{contract: contract}, nil -} - -// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { - contract, err := bindSystemMessage(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &SystemMessageTransactor{contract: contract}, nil -} - -// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { - contract, err := bindSystemMessage(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &SystemMessageFilterer{contract: contract}, nil -} - -// bindSystemMessage binds a generic wrapper to an already deployed contract. -func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transact(opts, method, params...) -} - -// TipsMetaData contains all meta data concerning the Tips contract. -var TipsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f4b0c5da8d8500be15e8a6f6d90648b0986dc65efa9dc5ee5f3d1e21baacc75c64736f6c634300080d0033", +// SystemContractMetaData contains all meta data concerning the SystemContract contract. +var SystemContractMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8d3638f4": "localDomain()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "b7bc563e": "setSystemMessenger(address)", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + }, } -// TipsABI is the input ABI used to generate the binding from. -// Deprecated: Use TipsMetaData.ABI instead. -var TipsABI = TipsMetaData.ABI - -// TipsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TipsMetaData.Bin instead. -var TipsBin = TipsMetaData.Bin - -// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. -func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { - parsed, err := TipsMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// SystemContractABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemContractMetaData.ABI instead. +var SystemContractABI = SystemContractMetaData.ABI - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil -} +// Deprecated: Use SystemContractMetaData.Sigs instead. +// SystemContractFuncSigs maps the 4-byte function signature to its string representation. +var SystemContractFuncSigs = SystemContractMetaData.Sigs -// Tips is an auto generated Go binding around an Ethereum contract. -type Tips struct { - TipsCaller // Read-only binding to the contract - TipsTransactor // Write-only binding to the contract - TipsFilterer // Log filterer for contract events +// SystemContract is an auto generated Go binding around an Ethereum contract. +type SystemContract struct { + SystemContractCaller // Read-only binding to the contract + SystemContractTransactor // Write-only binding to the contract + SystemContractFilterer // Log filterer for contract events } -// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TipsCaller struct { +// SystemContractCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemContractCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TipsTransactor struct { +// SystemContractTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemContractTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TipsFilterer struct { +// SystemContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemContractFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsSession is an auto generated Go binding around an Ethereum contract, +// SystemContractSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TipsSession struct { - Contract *Tips // Generic contract binding to set the session for +type SystemContractSession struct { + Contract *SystemContract // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TipsCallerSession struct { - Contract *TipsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemContractCallerSession struct { + Contract *SystemContractCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TipsTransactorSession struct { - Contract *TipsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemContractTransactorSession struct { + Contract *SystemContractTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TipsRaw struct { - Contract *Tips // Generic contract binding to access the raw methods on +// SystemContractRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemContractRaw struct { + Contract *SystemContract // Generic contract binding to access the raw methods on } -// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TipsCallerRaw struct { - Contract *TipsCaller // Generic read-only contract binding to access the raw methods on +// SystemContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemContractCallerRaw struct { + Contract *SystemContractCaller // Generic read-only contract binding to access the raw methods on } -// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TipsTransactorRaw struct { - Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on +// SystemContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemContractTransactorRaw struct { + Contract *SystemContractTransactor // Generic write-only contract binding to access the raw methods on } -// NewTips creates a new instance of Tips, bound to a specific deployed contract. -func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { - contract, err := bindTips(address, backend, backend, backend) +// NewSystemContract creates a new instance of SystemContract, bound to a specific deployed contract. +func NewSystemContract(address common.Address, backend bind.ContractBackend) (*SystemContract, error) { + contract, err := bindSystemContract(address, backend, backend, backend) if err != nil { return nil, err } - return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil + return &SystemContract{SystemContractCaller: SystemContractCaller{contract: contract}, SystemContractTransactor: SystemContractTransactor{contract: contract}, SystemContractFilterer: SystemContractFilterer{contract: contract}}, nil } -// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. -func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { - contract, err := bindTips(address, caller, nil, nil) +// NewSystemContractCaller creates a new read-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractCaller(address common.Address, caller bind.ContractCaller) (*SystemContractCaller, error) { + contract, err := bindSystemContract(address, caller, nil, nil) if err != nil { return nil, err } - return &TipsCaller{contract: contract}, nil + return &SystemContractCaller{contract: contract}, nil } -// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. -func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { - contract, err := bindTips(address, nil, transactor, nil) +// NewSystemContractTransactor creates a new write-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemContractTransactor, error) { + contract, err := bindSystemContract(address, nil, transactor, nil) if err != nil { return nil, err } - return &TipsTransactor{contract: contract}, nil + return &SystemContractTransactor{contract: contract}, nil } -// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. -func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { - contract, err := bindTips(address, nil, nil, filterer) +// NewSystemContractFilterer creates a new log filterer instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemContractFilterer, error) { + contract, err := bindSystemContract(address, nil, nil, filterer) if err != nil { return nil, err } - return &TipsFilterer{contract: contract}, nil + return &SystemContractFilterer{contract: contract}, nil } -// bindTips binds a generic wrapper to an already deployed contract. -func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TipsABI)) +// bindSystemContract binds a generic wrapper to an already deployed contract. +func bindSystemContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemContractABI)) if err != nil { return nil, err } @@ -5823,237 +7448,500 @@ func bindTips(address common.Address, caller bind.ContractCaller, transactor bin // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.SystemContractCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transfer(opts) +func (_SystemContract *SystemContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.contract.Transfer(opts) +func (_SystemContract *SystemContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transact(opts, method, params...) } -// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. -var TypeCastsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f48e7743f5652bcabb07b0c6a811bb87e95c3ee03c5f58210c9b4c41de216c3564736f6c634300080d0033", +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// TypeCastsABI is the input ABI used to generate the binding from. -// Deprecated: Use TypeCastsMetaData.ABI instead. -var TypeCastsABI = TypeCastsMetaData.ABI +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} -// TypeCastsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypeCastsMetaData.Bin instead. -var TypeCastsBin = TypeCastsMetaData.Bin +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCallerSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "owner") -// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. -func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { - parsed, err := TypeCastsMetaData.GetAbi() if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + return *new(common.Address), err } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCallerSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "systemMessenger") + if err != nil { - return common.Address{}, nil, nil, err + return *new(common.Address), err } - return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// TypeCasts is an auto generated Go binding around an Ethereum contract. -type TypeCasts struct { - TypeCastsCaller // Read-only binding to the contract - TypeCastsTransactor // Write-only binding to the contract - TypeCastsFilterer // Log filterer for contract events +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypeCastsCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCallerSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypeCastsTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "renounceOwnership") } -// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypeCastsFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) } -// TypeCastsSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type TypeCastsSession struct { - Contract *TypeCasts // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// SystemContractInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the SystemContract contract. +type SystemContractInitializedIterator struct { + Event *SystemContractInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type TypeCastsCallerSession struct { - Contract *TypeCastsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type TypeCastsTransactorSession struct { - Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypeCastsRaw struct { - Contract *TypeCasts // Generic contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractInitializedIterator) Error() error { + return it.fail } -// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypeCastsCallerRaw struct { - Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypeCastsTransactorRaw struct { - Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on +// SystemContractInitialized represents a Initialized event raised by the SystemContract contract. +type SystemContractInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { - contract, err := bindTypeCasts(address, backend, backend, backend) +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) FilterInitialized(opts *bind.FilterOpts) (*SystemContractInitializedIterator, error) { + + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + return &SystemContractInitializedIterator{contract: _SystemContract.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { - contract, err := bindTypeCasts(address, caller, nil, nil) +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *SystemContractInitialized) (event.Subscription, error) { + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypeCastsCaller{contract: contract}, nil + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { - contract, err := bindTypeCasts(address, nil, transactor, nil) - if err != nil { +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) ParseInitialized(log types.Log) (*SystemContractInitialized, error) { + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } - return &TypeCastsTransactor{contract: contract}, nil + event.Raw = log + return event, nil } -// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { - contract, err := bindTypeCasts(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &TypeCastsFilterer{contract: contract}, nil +// SystemContractOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the SystemContract contract. +type SystemContractOwnershipTransferredIterator struct { + Event *SystemContractOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// bindTypeCasts binds a generic wrapper to an already deployed contract. -func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) - if err != nil { - return nil, err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractOwnershipTransferredIterator) Error() error { + return it.fail } -// Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.contract.Call(opts, result, method, params...) +// SystemContractOwnershipTransferred represents a OwnershipTransferred event raised by the SystemContract contract. +type SystemContractOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transfer(opts) +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*SystemContractOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &SystemContractOwnershipTransferredIterator{contract: _SystemContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transact(opts, method, params...) +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *SystemContractOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. -var TypedMemViewMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "f26be3fc": "NULL()", - }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212209f79b827606424be1f696b438c892aaa1ea2217c087a982a1bc8e2c068d4334264736f6c634300080d0033", +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) ParseOwnershipTransferred(log types.Log) (*SystemContractOwnershipTransferred, error) { + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// TypedMemViewABI is the input ABI used to generate the binding from. -// Deprecated: Use TypedMemViewMetaData.ABI instead. -var TypedMemViewABI = TypedMemViewMetaData.ABI +// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. +var SystemMessageMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122064d0c81f40cd6947972ebb8451702ae66bd4d98b852c09adbce7930c7d6189d564736f6c634300080d0033", +} -// Deprecated: Use TypedMemViewMetaData.Sigs instead. -// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. -var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs +// SystemMessageABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemMessageMetaData.ABI instead. +var SystemMessageABI = SystemMessageMetaData.ABI -// TypedMemViewBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypedMemViewMetaData.Bin instead. -var TypedMemViewBin = TypedMemViewMetaData.Bin +// SystemMessageBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SystemMessageMetaData.Bin instead. +var SystemMessageBin = SystemMessageMetaData.Bin -// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. -func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { - parsed, err := TypedMemViewMetaData.GetAbi() +// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. +func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { + parsed, err := SystemMessageMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -6061,111 +7949,111 @@ func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) ( return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// TypedMemView is an auto generated Go binding around an Ethereum contract. -type TypedMemView struct { - TypedMemViewCaller // Read-only binding to the contract - TypedMemViewTransactor // Write-only binding to the contract - TypedMemViewFilterer // Log filterer for contract events +// SystemMessage is an auto generated Go binding around an Ethereum contract. +type SystemMessage struct { + SystemMessageCaller // Read-only binding to the contract + SystemMessageTransactor // Write-only binding to the contract + SystemMessageFilterer // Log filterer for contract events } -// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypedMemViewCaller struct { +// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemMessageCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypedMemViewTransactor struct { +// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemMessageTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypedMemViewFilterer struct { +// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemMessageFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// SystemMessageSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TypedMemViewSession struct { - Contract *TypedMemView // Generic contract binding to set the session for +type SystemMessageSession struct { + Contract *SystemMessage // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TypedMemViewCallerSession struct { - Contract *TypedMemViewCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemMessageCallerSession struct { + Contract *SystemMessageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TypedMemViewTransactorSession struct { - Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemMessageTransactorSession struct { + Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypedMemViewRaw struct { - Contract *TypedMemView // Generic contract binding to access the raw methods on +// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemMessageRaw struct { + Contract *SystemMessage // Generic contract binding to access the raw methods on } -// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypedMemViewCallerRaw struct { - Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on +// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemMessageCallerRaw struct { + Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on } -// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypedMemViewTransactorRaw struct { - Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on +// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemMessageTransactorRaw struct { + Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on } -// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { - contract, err := bindTypedMemView(address, backend, backend, backend) +// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { + contract, err := bindSystemMessage(address, backend, backend, backend) if err != nil { return nil, err } - return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { - contract, err := bindTypedMemView(address, caller, nil, nil) +// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { + contract, err := bindSystemMessage(address, caller, nil, nil) if err != nil { return nil, err } - return &TypedMemViewCaller{contract: contract}, nil + return &SystemMessageCaller{contract: contract}, nil } -// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { - contract, err := bindTypedMemView(address, nil, transactor, nil) +// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { + contract, err := bindSystemMessage(address, nil, transactor, nil) if err != nil { return nil, err } - return &TypedMemViewTransactor{contract: contract}, nil + return &SystemMessageTransactor{contract: contract}, nil } -// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { - contract, err := bindTypedMemView(address, nil, nil, filterer) +// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { + contract, err := bindSystemMessage(address, nil, nil, filterer) if err != nil { return nil, err } - return &TypedMemViewFilterer{contract: contract}, nil + return &SystemMessageFilterer{contract: contract}, nil } -// bindTypedMemView binds a generic wrapper to an already deployed contract. -func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) +// bindSystemMessage binds a generic wrapper to an already deployed contract. +func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) if err != nil { return nil, err } @@ -6176,191 +8064,169 @@ func bindTypedMemView(address common.Address, caller bind.ContractCaller, transa // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) +func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transfer(opts) +func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transact(opts, method, params...) -} - -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { - var out []interface{} - err := _TypedMemView.contract.Call(opts, &out, "NULL") - - if err != nil { - return *new([29]byte), err - } - - out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - - return out0, err - +func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transact(opts, method, params...) } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) +// TipsMetaData contains all meta data concerning the Tips contract. +var TipsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202d2bf16beb89b80167034b16fe5667642e695a1bdc96830cc9d5c528b112a31a64736f6c634300080d0033", } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) -} +// TipsABI is the input ABI used to generate the binding from. +// Deprecated: Use TipsMetaData.ABI instead. +var TipsABI = TipsMetaData.ABI -// UpdaterStorageMetaData contains all meta data concerning the UpdaterStorage contract. -var UpdaterStorageMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "8d3638f4": "localDomain()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "b7bc563e": "setSystemMessenger(address)", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "df034cd0": "updater()", - }, -} +// TipsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TipsMetaData.Bin instead. +var TipsBin = TipsMetaData.Bin -// UpdaterStorageABI is the input ABI used to generate the binding from. -// Deprecated: Use UpdaterStorageMetaData.ABI instead. -var UpdaterStorageABI = UpdaterStorageMetaData.ABI +// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. +func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { + parsed, err := TipsMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } -// Deprecated: Use UpdaterStorageMetaData.Sigs instead. -// UpdaterStorageFuncSigs maps the 4-byte function signature to its string representation. -var UpdaterStorageFuncSigs = UpdaterStorageMetaData.Sigs + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil +} -// UpdaterStorage is an auto generated Go binding around an Ethereum contract. -type UpdaterStorage struct { - UpdaterStorageCaller // Read-only binding to the contract - UpdaterStorageTransactor // Write-only binding to the contract - UpdaterStorageFilterer // Log filterer for contract events +// Tips is an auto generated Go binding around an Ethereum contract. +type Tips struct { + TipsCaller // Read-only binding to the contract + TipsTransactor // Write-only binding to the contract + TipsFilterer // Log filterer for contract events } -// UpdaterStorageCaller is an auto generated read-only Go binding around an Ethereum contract. -type UpdaterStorageCaller struct { +// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TipsCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactor struct { +// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TipsTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UpdaterStorageFilterer struct { +// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TipsFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageSession is an auto generated Go binding around an Ethereum contract, +// TipsSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type UpdaterStorageSession struct { - Contract *UpdaterStorage // Generic contract binding to set the session for +type TipsSession struct { + Contract *Tips // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type UpdaterStorageCallerSession struct { - Contract *UpdaterStorageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type TipsCallerSession struct { + Contract *TipsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// UpdaterStorageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type UpdaterStorageTransactorSession struct { - Contract *UpdaterStorageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type TipsTransactorSession struct { + Contract *TipsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageRaw is an auto generated low-level Go binding around an Ethereum contract. -type UpdaterStorageRaw struct { - Contract *UpdaterStorage // Generic contract binding to access the raw methods on +// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TipsRaw struct { + Contract *Tips // Generic contract binding to access the raw methods on } -// UpdaterStorageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UpdaterStorageCallerRaw struct { - Contract *UpdaterStorageCaller // Generic read-only contract binding to access the raw methods on +// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TipsCallerRaw struct { + Contract *TipsCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactorRaw struct { - Contract *UpdaterStorageTransactor // Generic write-only contract binding to access the raw methods on +// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TipsTransactorRaw struct { + Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on } -// NewUpdaterStorage creates a new instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorage(address common.Address, backend bind.ContractBackend) (*UpdaterStorage, error) { - contract, err := bindUpdaterStorage(address, backend, backend, backend) +// NewTips creates a new instance of Tips, bound to a specific deployed contract. +func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { + contract, err := bindTips(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorage{UpdaterStorageCaller: UpdaterStorageCaller{contract: contract}, UpdaterStorageTransactor: UpdaterStorageTransactor{contract: contract}, UpdaterStorageFilterer: UpdaterStorageFilterer{contract: contract}}, nil + return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil } -// NewUpdaterStorageCaller creates a new read-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageCaller(address common.Address, caller bind.ContractCaller) (*UpdaterStorageCaller, error) { - contract, err := bindUpdaterStorage(address, caller, nil, nil) +// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. +func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { + contract, err := bindTips(address, caller, nil, nil) if err != nil { return nil, err } - return &UpdaterStorageCaller{contract: contract}, nil + return &TipsCaller{contract: contract}, nil } -// NewUpdaterStorageTransactor creates a new write-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageTransactor(address common.Address, transactor bind.ContractTransactor) (*UpdaterStorageTransactor, error) { - contract, err := bindUpdaterStorage(address, nil, transactor, nil) +// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. +func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { + contract, err := bindTips(address, nil, transactor, nil) if err != nil { return nil, err } - return &UpdaterStorageTransactor{contract: contract}, nil + return &TipsTransactor{contract: contract}, nil } -// NewUpdaterStorageFilterer creates a new log filterer instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageFilterer(address common.Address, filterer bind.ContractFilterer) (*UpdaterStorageFilterer, error) { - contract, err := bindUpdaterStorage(address, nil, nil, filterer) +// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. +func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { + contract, err := bindTips(address, nil, nil, filterer) if err != nil { return nil, err } - return &UpdaterStorageFilterer{contract: contract}, nil + return &TipsFilterer{contract: contract}, nil } -// bindUpdaterStorage binds a generic wrapper to an already deployed contract. -func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(UpdaterStorageABI)) +// bindTips binds a generic wrapper to an already deployed contract. +func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TipsABI)) if err != nil { return nil, err } @@ -6371,810 +8237,422 @@ func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.UpdaterStorageCaller.contract.Call(opts, result, method, params...) +func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transfer(opts) +func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transact(opts, method, params...) +func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.contract.Call(opts, result, method, params...) +func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transfer(opts) +func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transact(opts, method, params...) -} - -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "localDomain") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - +func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.contract.Transact(opts, method, params...) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) +// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. +var TypeCastsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a8fe757644021462d97ec3a29541a08b6f3014908c27607b430ac007c5a339f064736f6c634300080d0033", } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCallerSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) -} +// TypeCastsABI is the input ABI used to generate the binding from. +// Deprecated: Use TypeCastsMetaData.ABI instead. +var TypeCastsABI = TypeCastsMetaData.ABI -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "owner") +// TypeCastsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypeCastsMetaData.Bin instead. +var TypeCastsBin = TypeCastsMetaData.Bin +// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. +func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { + parsed, err := TypeCastsMetaData.GetAbi() if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "systemMessenger") - - if err != nil { - return *new(common.Address), err + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "updater") - + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "setSystemMessenger", _systemMessenger) + return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// TypeCasts is an auto generated Go binding around an Ethereum contract. +type TypeCasts struct { + TypeCastsCaller // Read-only binding to the contract + TypeCastsTransactor // Write-only binding to the contract + TypeCastsFilterer // Log filterer for contract events } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypeCastsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "transferOwnership", newOwner) +// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypeCastsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypeCastsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +// TypeCastsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypeCastsSession struct { + Contract *TypeCasts // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the UpdaterStorage contract. -type UpdaterStorageInitializedIterator struct { - Event *UpdaterStorageInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypeCastsCallerSession struct { + Contract *TypeCastsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypeCastsTransactorSession struct { + Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageInitializedIterator) Error() error { - return it.fail +// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypeCastsRaw struct { + Contract *TypeCasts // Generic contract binding to access the raw methods on } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil +// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypeCastsCallerRaw struct { + Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageInitialized represents a Initialized event raised by the UpdaterStorage contract. -type UpdaterStorageInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypeCastsTransactorRaw struct { + Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterInitialized(opts *bind.FilterOpts) (*UpdaterStorageInitializedIterator, error) { - - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Initialized") +// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { + contract, err := bindTypeCasts(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorageInitializedIterator{contract: _UpdaterStorage.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *UpdaterStorageInitialized) (event.Subscription, error) { - - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Initialized") +// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { + contract, err := bindTypeCasts(address, caller, nil, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypeCastsCaller{contract: contract}, nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseInitialized(log types.Log) (*UpdaterStorageInitialized, error) { - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { +// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { + contract, err := bindTypeCasts(address, nil, transactor, nil) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &TypeCastsTransactor{contract: contract}, nil } -// UpdaterStorageNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdaterIterator struct { - Event *UpdaterStorageNewUpdater // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { + contract, err := bindTypeCasts(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TypeCastsFilterer{contract: contract}, nil } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// bindTypeCasts binds a generic wrapper to an already deployed contract. +func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) + if err != nil { + return nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageNewUpdaterIterator) Error() error { - return it.fail +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.contract.Call(opts, result, method, params...) } -// UpdaterStorageNewUpdater represents a NewUpdater event raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transfer(opts) } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*UpdaterStorageNewUpdaterIterator, error) { +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transact(opts, method, params...) +} - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "NewUpdater") - if err != nil { - return nil, err - } - return &UpdaterStorageNewUpdaterIterator{contract: _UpdaterStorage.contract, event: "NewUpdater", logs: logs, sub: sub}, nil +// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. +var TypedMemViewMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "f26be3fc": "NULL()", + }, + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212209b09e3cec3dad3609669ed2c818a86ed95b44328b4061647e48d11b465c3cd8464736f6c634300080d0033", } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *UpdaterStorageNewUpdater) (event.Subscription, error) { +// TypedMemViewABI is the input ABI used to generate the binding from. +// Deprecated: Use TypedMemViewMetaData.ABI instead. +var TypedMemViewABI = TypedMemViewMetaData.ABI + +// Deprecated: Use TypedMemViewMetaData.Sigs instead. +// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. +var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs + +// TypedMemViewBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypedMemViewMetaData.Bin instead. +var TypedMemViewBin = TypedMemViewMetaData.Bin - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "NewUpdater") +// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. +func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { + parsed, err := TypedMemViewMetaData.GetAbi() if err != nil { - return nil, err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseNewUpdater(log types.Log) (*UpdaterStorageNewUpdater, error) { - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return nil, err + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } - event.Raw = log - return event, nil + return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil } -// UpdaterStorageOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferredIterator struct { - Event *UpdaterStorageOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// TypedMemView is an auto generated Go binding around an Ethereum contract. +type TypedMemView struct { + TypedMemViewCaller // Read-only binding to the contract + TypedMemViewTransactor // Write-only binding to the contract + TypedMemViewFilterer // Log filterer for contract events +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypedMemViewCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypedMemViewTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypedMemViewFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypedMemViewSession struct { + Contract *TypedMemView // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageOwnershipTransferredIterator) Error() error { - return it.fail +// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypedMemViewCallerSession struct { + Contract *TypedMemViewCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil +// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypedMemViewTransactorSession struct { + Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageOwnershipTransferred represents a OwnershipTransferred event raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypedMemViewRaw struct { + Contract *TypedMemView // Generic contract binding to access the raw methods on } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UpdaterStorageOwnershipTransferredIterator, error) { +// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypedMemViewCallerRaw struct { + Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on +} - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypedMemViewTransactorRaw struct { + Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on +} - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { + contract, err := bindTypedMemView(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorageOwnershipTransferredIterator{contract: _UpdaterStorage.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UpdaterStorageOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) +// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { + contract, err := bindTypedMemView(address, caller, nil, nil) + if err != nil { + return nil, err } + return &TypedMemViewCaller{contract: contract}, nil +} - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { + contract, err := bindTypedMemView(address, nil, transactor, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypedMemViewTransactor{contract: contract}, nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseOwnershipTransferred(log types.Log) (*UpdaterStorageOwnershipTransferred, error) { - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { + contract, err := bindTypedMemView(address, nil, nil, filterer) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &TypedMemViewFilterer{contract: contract}, nil } -// UpdaterStorageUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the UpdaterStorage contract. -type UpdaterStorageUpdateIterator struct { - Event *UpdaterStorageUpdate // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// bindTypedMemView binds a generic wrapper to an already deployed contract. +func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageUpdateIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageUpdateIterator) Error() error { - return it.fail +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.contract.Call(opts, result, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageUpdateIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transfer(opts) } -// UpdaterStorageUpdate represents a Update event raised by the UpdaterStorage contract. -type UpdaterStorageUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transact(opts, method, params...) } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*UpdaterStorageUpdateIterator, error) { - - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { + var out []interface{} + err := _TypedMemView.contract.Call(opts, &out, "NULL") - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new([29]byte), err } - return &UpdaterStorageUpdateIterator{contract: _UpdaterStorage.contract, event: "Update", logs: logs, sub: sub}, nil -} -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. -// -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *UpdaterStorageUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { + out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } + return out0, err - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { - return err - } - event.Raw = log +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. +// +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseUpdate(log types.Log) (*UpdaterStorageUpdate, error) { - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } // Version0MetaData contains all meta data concerning the Version0 contract. @@ -7183,7 +8661,7 @@ var Version0MetaData = &bind.MetaData{ Sigs: map[string]string{ "ffa1ad74": "VERSION()", }, - Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220604fcf8af2331bdc47a138d33f1aff2296b23b6ac6241b3700915f6276da443f64736f6c634300080d0033", + Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212201b482fe10d1ef874b5b4f4278fc44676f2b0c3af160b101d71eb7da4a81e5da364736f6c634300080d0033", } // Version0ABI is the input ABI used to generate the binding from. diff --git a/core/contracts/home/home.contractinfo.json b/core/contracts/home/home.contractinfo.json index 6b94d51bb8..ea57483ac1 100644 --- a/core/contracts/home/home.contractinfo.json +++ b/core/contracts/home/home.contractinfo.json @@ -1 +1 @@ -{"solidity/Home.sol:Address":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220854d99b9e1772a582bb7f179bbc72ab60a19d5a9c8c31114f5d0ce41943177ba64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220854d99b9e1772a582bb7f179bbc72ab60a19d5a9c8c31114f5d0ce41943177ba64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"96866:8061:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;96866:8061:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"96866:8061:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Address\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208f6e8c5d5e570a09438453c278bf2a3367e949e075723f8b4687f291d788d0f964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208f6e8c5d5e570a09438453c278bf2a3367e949e075723f8b4687f291d788d0f964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"53527:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;53527:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"53527:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a33850447495ba5898fec6f32aaada16448f91bd7c415fdddf1f853041113b7764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a33850447495ba5898fec6f32aaada16448f91bd7c415fdddf1f853041113b7764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"73027:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;73027:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"73027:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122088dedff94379c65ec0f5e9cca1e016a7c559c6466418a6c05dd1facd4682709e64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122088dedff94379c65ec0f5e9cca1e016a7c559c6466418a6c05dd1facd4682709e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"76245:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;76245:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"76245:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:AuthManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"AuthManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206f9d8415999e703353a5cf87a07ced8e4954b1ee8a0ecc7a228eb46deef1fca564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206f9d8415999e703353a5cf87a07ced8e4954b1ee8a0ecc7a228eb46deef1fca564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44461:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;44461:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"44461:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202e677156b343adc866709487e1813ebe40c4d10a6a8e096fac1ffb6a59693f3364736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202e677156b343adc866709487e1813ebe40c4d10a6a8e096fac1ffb6a59693f3364736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"39177:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;39177:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"39177:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Home":{"code":"0x60a06040523480156200001157600080fd5b50604051620036d9380380620036d9833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b60805161363d6200009c6000396000818161025e01528181610d9c01526117a3015261363d6000f3fe6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220b22f209b5f062fc859601394f10100b84c7771bbdf8c9334225113abaf846cbf64736f6c634300080d0033","runtime-code":"0x6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220b22f209b5f062fc859601394f10100b84c7771bbdf8c9334225113abaf846cbf64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"105382:12592:0:-:0;;;108412:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71588:26;;;;105382:12592;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;105382:12592:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"105382:12592:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96350:81;;;;;;;;;;-1:-1:-1;96414:10:0;;96350:81;;;160:25:1;;;148:2;133:18;96350:81:0;;;;;;;;114211:776;;;;;;;;;;-1:-1:-1;114211:776:0;;;;;:::i;:::-;;:::i;:::-;;;1657:14:1;;1650:22;1632:41;;1620:2;1605:18;114211:776:0;1492:187:1;112660:257:0;;;;;;;;;;;;;:::i;:::-;;;;1886:10:1;1874:23;;;1856:42;;1929:2;1914:18;;1907:34;;;;1829:18;112660:257:0;1684:263:1;106264:58:0;;;;;;;;;;;;106313:9;106264:58;;72939:84;;;;;;;;;;;;;:::i;:::-;;95894:32;;;;;;;;;;-1:-1:-1;95894:32:0;;;;;:::i;:::-;;:::i;70386:35::-;;;;;;;;;;;;;;;;;;2493:10:1;2481:23;;;2463:42;;2451:2;2436:18;70386:35:0;2319:192:1;68483:85:0;;;;;;;;;;-1:-1:-1;68555:6:0;;;;68483:85;;;2692:42:1;2680:55;;;2662:74;;2650:2;2635:18;68483:85:0;2516:226:1;110301:140:0;;;;;;;;;;-1:-1:-1;110301:140:0;;;;;:::i;:::-;;:::i;109662:220::-;;;;;;;;;;-1:-1:-1;109662:220:0;;;;;:::i;:::-;;:::i;106537:37::-;;;;;;;;;;-1:-1:-1;106537:37:0;;;;;;;;;;;106441:19;;;;;;;;;;-1:-1:-1;106441:19:0;;;;;;;;72137:133;;;;;;;;;;-1:-1:-1;72137:133:0;;;;;:::i;:::-;;:::i;106613:19::-;;;;;;;;;;-1:-1:-1;106613:19:0;;;;;;;;;;;;;;;;;;:::i;108568:394::-;;;;;;;;;;-1:-1:-1;108568:394:0;;;;;:::i;:::-;;:::i;70541:39::-;;;;;;;;;;-1:-1:-1;70541:39:0;;;;;;;;70512:22;;;;;;;;;;-1:-1:-1;70512:22:0;;;;;;;;96166:81;;;;;;;;;;;;;:::i;69365:198::-;;;;;;;;;;-1:-1:-1;69365:198:0;;;;;:::i;:::-;;:::i;110947:1473::-;;;;;;:::i;:::-;;:::i;95862:26::-;;;;;;;;;;-1:-1:-1;95862:26:0;;;;;;50:33;;;;;;;;;;;;82:1;50:33;;;;;5906:4:1;5894:17;;;5876:36;;5864:2;5849:18;50:33:0;5734:184:1;114211:776:0;114293:4;109380:13;109371:5;;;;;;;:22;;;;;;;;:::i;:::-;;109363:47;;;;-1:-1:-1;;;109363:47:0;;6125:2:1;109363:47:0;;;6107:21:1;6164:2;6144:18;;;6137:30;6203:14;6183:18;;;6176:42;6235:18;;109363:47:0;;;;;;;;;114364:16:::1;114382:13:::0;114399:31:::1;114417:12;114399:17;:31::i;:::-;114363:67;;;;114440:13;114456:24;:5;:22;;;;:24::i;:::-;114440:40:::0;-1:-1:-1;114490:13:0::1;114506:23;-1:-1:-1::0;;114506:21:0;::::1;;:23::i;:::-;114614:15;:22:::0;114490:39;;-1:-1:-1;114605:31:0::1;::::0;::::1;;114601:284;;;114665:15;114681:6;114665:23;;;;;;;;;;:::i;:::-;;;;;;;;;114656:5;:32:::0;114652:139:::1;;-1:-1:-1::0;114771:5:0::1;::::0;114211:776;-1:-1:-1;;;;;114211:776:0:o;114652:139::-:1;114894:7;:5;:7::i;:::-;114916:43;114936:8;114946:12;114916:43;;;;;;;:::i;:::-;;;;;;;;114976:4;114969:11;;;;;;109420:1;114211:776:::0;;;:::o;112660:257::-;112765:15;:22;112708:13;;;;112801:11;;112797:114;;112844:10;112853:1;112844:6;:10;:::i;:::-;112828:27;;112877:15;112893:6;112877:23;;;;;;;;;;:::i;:::-;;;;;;;;;112869:31;;112797:114;112738:179;112660:257;;:::o;72939:84::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;7900:2:1;68687:68:0;;;7882:21:1;;;7919:18;;;7912:30;7978:34;7958:18;;;7951:62;8030:18;;68687:68:0;7698:356:1;68687:68:0;72939:84::o;95894:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;95894:32:0;:::o;110301:140::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;7900:2:1;68687:68:0;;;7882:21:1;;;7919:18;;;7912:30;7978:34;7958:18;;;7951:62;8030:18;;68687:68:0;7698:356:1;68687:68:0;110382:52:::1;110417:15;110382:18;:52::i;:::-;110301:140:::0;:::o;109662:220::-;109176:14;;;;;;;109154:10;:37;109146:65;;;;-1:-1:-1;;;109146:65:0;;8261:2:1;109146:65:0;;;8243:21:1;8300:2;8280:18;;;8273:30;8339:17;8319:18;;;8312:45;8374:18;;109146:65:0;8059:339:1;109146:65:0;109738:21:::1;109750:8;109738:11;:21::i;:::-;-1:-1:-1::0;109854:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;109662:220::o;72137:133::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;7900:2:1;68687:68:0;;;7882:21:1;;;7919:18;;;7912:30;7978:34;7958:18;;;7951:62;8030:18;;68687:68:0;7698:356:1;68687:68:0;72229:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;72137:133::o;108568:394::-;61379:19;61401:25;61424:1;61401:22;:25::i;:::-;61379:47;;61440:14;61436:65;;;61470:13;:20;;;;;;;;61436:65;108715:35:::1;108734:15;108715:18;:35::i;:::-;108760:50;108785:14;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108760;:50::i;:::-;108820:5;:21:::0;;;::::1;::::0;::::1;::::0;;108922:15:::1;:33:::0;;-1:-1:-1;108922:33:0;::::1;::::0;;-1:-1:-1;108922:33:0;;;;::::1;::::0;61521:99;;;;61555:13;:21;;;;;;61595:14;;-1:-1:-1;5876:36:1;;61595:14:0;;5864:2:1;5849:18;61595:14:0;;;;;;;;61521:99;61369:257;108568:394;:::o;96166:81::-;96203:7;96229:11;:4;:9;:11::i;:::-;96222:18;;96166:81;:::o;69365:198::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;7900:2:1;68687:68:0;;;7882:21:1;;;7919:18;;;7912:30;7978:34;7958:18;;;7951:62;8030:18;;68687:68:0;7698:356:1;68687:68:0;69453:22:::1;::::0;::::1;69445:73;;;::::0;-1:-1:-1;;;69445:73:0;;9060:2:1;69445:73:0::1;::::0;::::1;9042:21:1::0;9099:2;9079:18;;;9072:30;9138:34;9118:18;;;9111:62;9209:8;9189:18;;;9182:36;9235:19;;69445:73:0::1;8858:402:1::0;69445:73:0::1;69528:28;69547:8;69528:18;:28::i;110947:1473::-:0;109380:13;109371:5;;;;;;;:22;;;;;;;;:::i;:::-;;109363:47;;;;-1:-1:-1;;;109363:47:0;;6125:2:1;109363:47:0;;;6107:21:1;6164:2;6144:18;;;6137:30;6203:14;6183:18;;;6176:42;6235:18;;109363:47:0;5923:336:1;109363:47:0;106313:9:::1;111184:12;:19;:45;;111176:70;;;::::0;-1:-1:-1;;;111176:70:0;;9467:2:1;111176:70:0::1;::::0;::::1;9449:21:1::0;9506:2;9486:18;;;9479:30;9545:14;9525:18;;;9518:42;9577:18;;111176:70:0::1;9265:336:1::0;111176:70:0::1;111296:9;111264:28;:16;:5;:14;:16::i;:::-;-1:-1:-1::0;;111264:26:0::1;;:28::i;:::-;:41;;;111256:59;;;::::0;-1:-1:-1;;;111256:59:0;;9808:2:1;111256:59:0::1;::::0;::::1;9790:21:1::0;9847:1;9827:18;;;9820:29;9885:7;9865:18;;;9858:35;9910:18;;111256:59:0::1;9606:328:1::0;111256:59:0::1;111409:5;::::0;:9:::1;::::0;:5:::1;;::::0;:9:::1;:::i;:::-;111401:5;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;111446:41:0::1;111469:17:::0;111446:22:::1;:41::i;:::-;111647:5;::::0;40462:242;;;13565:16:1;40462:242:0;;;13549:102:1;13670:66;111601:11:0::1;13773:3:1::0;13769:16;;;13765:25;;13752:11;;;13745:46;13807:11;;;13800:27;;;13861:16;;;;;13843:12;;;13836:47;13917:16;;;13913:25;;13899:12;;;13892:47;13955:12;;;13948:28;;;14010:16;;;;14006:25;;;13992:12;;;13985:47;40462:242:0;;;;;;;;;14048:12:1;;;;40462:242:0;;111428:59;;-1:-1:-1;111815:21:0::1;111839:51;111861:7;111870:5;111877:12;111839:21;:51::i;:::-;111981:19:::0;;::::1;::::0;::::1;::::0;111815:75;;-1:-1:-1;112063:25:0::1;111981:19:::0;112063:11:::1;:25::i;:::-;112356:5;::::0;::::1;;116363:2:::0;116339:26;;;;;116338:37;112242:171:::1;;112300:1;112290:7;96414:10:::0;;;96350:81;112290:7:::1;:11;;;;:::i;:::-;112264:12;112242:171;112376:5;112395:8;112242:171;;;;;;;:::i;:::-;;;;;;;;111166:1254;;;;110947:1473:::0;;;;;:::o;79047:474::-;79148:16;;79203:19;:12;79148:16;79203;:19::i;:::-;79195:27;-1:-1:-1;73720:2:0;3488:26;17310:2;17306:16;;;17302:28;74974:37;79232:52;;;;-1:-1:-1;;;79232:52:0;;10756:2:1;79232:52:0;;;10738:21:1;10795:2;10775:18;;;10768:30;10834:20;10814:18;;;10807:48;10872:18;;79232:52:0;10554:342:1;79232:52:0;79305:115;79337:23;-1:-1:-1;;79337:21:0;;;:23::i;:::-;79374:36;:28;-1:-1:-1;;79374:26:0;;;:28::i;:::-;-1:-1:-1;;79374:34:0;;:36::i;:::-;79305:18;:115::i;:::-;79294:126;-1:-1:-1;79438:47:0;79449:25;-1:-1:-1;;79449:23:0;;;:25::i;:::-;79476:8;79438:10;:47::i;:::-;79430:84;;;;-1:-1:-1;;;79430:84:0;;11103:2:1;79430:84:0;;;11085:21:1;11142:2;11122:18;;;11115:30;11181:26;11161:18;;;11154:54;11225:18;;79430:84:0;10901:348:1;79430:84:0;79047:474;;;:::o;75372:136::-;75436:6;75468:32;-1:-1:-1;;75468:15:0;;73614:1;;75468:15;:32::i;:::-;75454:47;75372:136;-1:-1:-1;;75372:136:0:o;75601:124::-;75664:7;75690:28;-1:-1:-1;;75690:11:0;;73661:1;75715:2;75690:11;:28::i;115609:231::-;115679:5;:21;;;;;;;;;;;;115735:48;;;;;115771:10;115735:14;:48;;2662:74:1;115735:14:0;;;;;;;;;;:27;;2635:18:1;;115735:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;115813:7:0;;115798:35;;115822:10;;-1:-1:-1;115798:35:0;115813:7;;;;-1:-1:-1;115798:35:0;;115813:7;;115798:35;115609:231::o;115161:285::-;98137:19;;;;115241:81;;;;-1:-1:-1;;;115241:81:0;;11703:2:1;115241:81:0;;;11685:21:1;11742:2;11722:18;;;11715:30;11781:26;11761:18;;;11754:54;11825:18;;115241:81:0;11501:348:1;115241:81:0;115332:14;:49;;;;;;;;;;;;;;;;;;115396:43;;2662:74:1;;;115396:43:0;;2650:2:1;2635:18;115396:43:0;;;;;;;115161:285;:::o;72567:179::-;72650:7;;;;72667:21;;;;;;;;;;;72703:36;;;72650:7;;;;12089:34:1;;;12154:2;12139:18;;12132:43;;;;72703:36:0;;12001:18:1;72703:36:0;11854:327:1;63555:808:0;63952:13;;63619:4;;63952:13;;;;;63948:409;;;64006:7;:12;;64017:1;64006:12;:61;;;;-1:-1:-1;64061:4:0;98137:19;:23;64006:61;63981:166;;;;-1:-1:-1;;;63981:166:0;;12388:2:1;63981:166:0;;;12370:21:1;12427:2;12407:18;;;12400:30;12466:34;12446:18;;;12439:62;12537:16;12517:18;;;12510:44;12571:19;;63981:166:0;12186:410:1;63981:166:0;-1:-1:-1;64168:5:0;;63555:808;-1:-1:-1;63555:808:0:o;63948:409::-;64212:12;;:22;;;;:12;;:22;64204:81;;;;-1:-1:-1;;;64204:81:0;;12388:2:1;64204:81:0;;;12370:21:1;12427:2;12407:18;;;12400:30;12466:34;12446:18;;;12439:62;12537:16;12517:18;;;12510:44;12571:19;;64204:81:0;12186:410:1;64204:81:0;-1:-1:-1;64299:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;63555:808:0:o;71673:142::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;12803:2:1;62958:69:0;;;12785:21:1;12842:2;12822:18;;;12815:30;12881:34;12861:18;;;12854:62;12952:13;12932:18;;;12925:41;12983:19;;62958:69:0;12601:407:1;62958:69:0;71761:16:::1;:14;:16::i;:::-;71787:21;71799:8;71787:11;:21::i;82634:122::-:0;82691:7;82717:32;82729:5;82736:12;:10;:12::i;:::-;82717:11;:32::i;69717:187::-;69809:6;;;;69825:17;;;;;;;;;;;69857:40;;69809:6;;;69825:17;69809:6;;69857:40;;69790:16;;69857:40;69780:124;69717:187;:::o;90222:122::-;90283:7;90309:28;:5;34906:10;90309:9;:28::i;91329:183::-;91402:6;91386:5;89229:35;34906:10;34899:18;-1:-1:-1;;89229:16:0;;;;:35::i;:::-;;91486:19:::1;91499:5;91486:12;:19::i;:::-;91467:16;91477:5;91467:9;:16::i;:::-;91447:17;91458:5;91447:10;:17::i;:::-;91427;91438:5;91427:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;91420:85;;89274:1;91329:183:::0;;;;:::o;117158:814::-;117264:14;92147:24;117298:48;;117294:672;;117398:10;117362:47;114211:776;-1:-1:-1;;114211:776:0:o;117294:672::-;117802:24;:22;:24::i;:::-;-1:-1:-1;92147:24:0;117158:814;;;:::o;36091:638::-;36387:14;;36236:12;;36344:17;;35842:29;35860:10;35713:1;35842:29;:::i;:::-;36364:13;;:38;;;;:::i;:::-;36344:58;;36412:17;36452:5;:12;36432:10;:33;;;;:::i;:::-;36412:53;-1:-1:-1;34563:1:0;35842:29;35860:10;35713:1;35842:29;:::i;:::-;36561:13;;36592:10;36620;36648:7;36673:5;36696:12;36494:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;36475:247;;;;36091:638;;;;;;:::o;96588:123::-;96643:18;:4;96655:5;96643:11;:18::i;:::-;96671:15;96692:11;:4;:9;:11::i;:::-;96671:33;;;;;;;-1:-1:-1;96671:33:0;;;;;;;;;;;-1:-1:-1;96588:123:0:o;14473:359::-;14577:10;;14543:7;;14724:4;14715:14;;14799:26;;;;14715:14;14577:10;14799:5;:26::i;:::-;14792:33;14473:359;-1:-1:-1;;;;;14473:359:0:o;75831:155::-;75894:7;75920:59;-1:-1:-1;;75920:11:0;;75894:7;73720:2;75894:7;75920:11;:59::i;76069:172::-;76137:7;76163:71;73720:2;76193:37;73720:2;17310;17306:16;;;3488:26;17302:28;76193:37;:::i;:::-;-1:-1:-1;;76163:11:0;;;:71;76232:1;76163:11;:71::i;29126:632::-;29181:16;29209:11;29230:12;29245;29249:7;17310:2;17306:16;3488:26;17302:28;;17064:282;29245:12;29230:27;;;;29367:4;29361:11;29354:18;;29422:3;29415:10;;29468:33;29481:7;29490:3;29496:4;29490:10;29468:12;:33::i;:::-;-1:-1:-1;29625:14:0;;;29641:4;29621:25;29615:4;29608:39;29688:17;;29126:632;;-1:-1:-1;29126:632:0:o;76568:285::-;76678:14;;76725;-1:-1:-1;;76725:12:0;;;:14::i;:::-;76708:31;;76758:36;76787:6;52303:58;;21315:66:1;52303:58:0;;;21303:79:1;21398:12;;;21391:28;;;52173:7:0;;21435:12:1;;52303:58:0;;;;;;;;;;;;52293:69;;;;;;52286:76;;52104:265;;;;76758:36;76749:45;;76813:33;76827:6;76835:10;76813:13;:33::i;:::-;76804:42;76568:285;-1:-1:-1;;;;76568:285:0:o;75115:143::-;75180:6;75212:38;-1:-1:-1;;75212:15:0;;75180:6;75248:1;75212:15;:38::i;116388:236::-;116510:4;116553:11;116538:26;;:11;:26;;;116530:51;;;;-1:-1:-1;;;116530:51:0;;15823:2:1;116530:51:0;;;15805:21:1;15862:2;15842:18;;;15835:30;15901:14;15881:18;;;15874:42;15933:18;;116530:51:0;15621:336:1;116530:51:0;-1:-1:-1;116610:7:0;;;;;;116598:19;;;;116388:236;-1:-1:-1;116388:236:0:o;21939:221::-;22058:14;22136:11;22141:6;22136:2;:11;:::i;:::-;22135:17;;22151:1;22135:17;:::i;:::-;22091:62;;22099:30;22105:7;22114:6;22122;22099:5;:30::i;:::-;22091:62;;;21939:221;-1:-1:-1;;;;21939:221:0:o;20822:771::-;20937:14;20967:6;:11;;20977:1;20967:11;20963:59;;-1:-1:-1;21009:1:0;20994:17;;20963:59;21053:12;21057:7;17310:2;17306:16;3488:26;17302:28;;17064:282;21053:12;21035:30;;:15;;;;:6;:15;:::i;:::-;:30;21031:137;;;21088:68;21104:12;21108:7;16204:3;16200:17;3488:26;16196:29;;15877:364;21104:12;21088:68;;21118:12;21122:7;17310:2;17306:16;3488:26;17302:28;;17064:282;21118:12;21088:68;;21132:6;21148;21140:15;;21088;:68::i;:::-;21081:76;;-1:-1:-1;;;21081:76:0;;;;;;;;:::i;21031:137::-;21195:2;21185:6;:12;;;;21177:83;;;;-1:-1:-1;;;21177:83:0;;16721:2:1;21177:83:0;;;16703:21:1;16760:2;16740:18;;;16733:30;16799:34;16779:18;;;16772:62;16870:28;16850:18;;;16843:56;16916:19;;21177:83:0;16519:422:1;21177:83:0;21341:1;21332:10;;21271:15;21377:12;21381:7;16204:3;16200:17;3488:26;16196:29;;15877:364;21377:12;21362:27;;;-1:-1:-1;21399:13:0;8306:66;8276:12;;;8255:131;21551:17;;;;21545:24;21541:36;;;-1:-1:-1;;;;;20822:771:0:o;68195:95::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;12803:2:1;62958:69:0;;;12785:21:1;12842:2;12822:18;;;12815:30;12881:34;12861:18;;;12854:62;12952:13;12932:18;;;12925:41;12983:19;;62958:69:0;12601:407:1;62958:69:0;68257:26:::1;:24;:26::i;82874:964::-:0;82919:34;;:::i;:::-;82978:3;82965:16;;83004:3;82965:10;82991;;:16;83030:3;83017:10;;;:16;83056:3;83043:10;;;:16;83082:3;83069:10;;;:16;83108:3;83095:10;;;:16;83134:3;83121:10;;;:16;83160:3;83147:10;;;:16;83186:3;83173:10;;;:16;83212:3;83199:10;;;:16;83239:4;83225:11;;;:18;83267:4;83253:11;;;:18;83295:4;83281:11;;;:18;83323:4;83309:11;;;:18;83351:4;83337:11;;;:18;83379:4;83365:11;;;:18;83407:4;83393:11;;;:18;83435:4;83421:11;;;:18;83463:4;83449:11;;;:18;83491:4;83477:11;;;:18;83519:4;83505:11;;;:18;83547:4;83533:11;;;:18;83575:4;83561:11;;;:18;83603:4;83589:11;;;:18;83631:4;83617:11;;;:18;83659:4;83645:11;;;:18;83687:4;83673:11;;;:18;83715:4;83701:11;;;:18;83743:4;83729:11;;;:18;83771:4;83757:11;;;:18;83799:4;83785:11;;;:18;83827:4;83813:11;;;:18;82965:7;82874:964::o;81978:589::-;82151:11;;;;82102:16;;;82173:388;80558:2;82193:1;:14;82173:388;;;82259:4;82244:11;;;82243:20;;;82281:12;;;82277:215;;82351:5;82364:1;82351:15;;;;;;;:::i;:::-;;;82334:43;;;;;;17103:19:1;;;;17138:12;;17131:28;;;17175:12;;82334:43:0;;;;;;;;;;;;82324:54;;;;;;82313:65;;82277:215;;;82455:8;82465:7;82473:1;82465:10;;;;;;;:::i;:::-;;;;;82438:38;;;;;;;;17103:19:1;;;17147:2;17138:12;;17131:28;17184:2;17175:12;;16946:247;82438:38:0;;;;;;;;;;;;;82428:49;;;;;;82417:60;;82277:215;-1:-1:-1;82533:3:0;;82173:388;;;;82124:443;81978:589;;;;:::o;10891:578::-;10969:7;10993:26;11000:7;11009:9;10993:6;:26::i;:::-;10988:451;;11038:9;11051:35;11069:15;11076:7;15235:3;15231:17;;15024:268;11069:15;11061:24;;11051:9;:35::i;:::-;11035:51;;;11103:9;11116:29;11134:9;11126:18;;11116:9;:29::i;:::-;11203:186;;17565:31:1;11203:186:0;;;17553:44:1;17616:66;17720:3;17716:16;;;17712:25;;17698:12;;;17691:47;17768:15;17754:12;;;17747:37;17818:16;;;17814:25;17800:12;;;17793:47;11100:45:0;;-1:-1:-1;11159:17:0;;-1:-1:-1;17856:12:1;;11203:186:0;;;;;;;;;;;;11159:244;;11424:3;11417:11;;-1:-1:-1;;;11417:11:0;;;;;;;;:::i;10988:451::-;-1:-1:-1;11455:7:0;;10891:578;-1:-1:-1;10891:578:0:o;91170:153::-;91246:6;91230:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;91278:37:0::1;-1:-1:-1::0;;91278:15:0;::::1;89177:2;91312;91278:15;:37::i;:::-;91264:52;;::::0;91170:153;-1:-1:-1;;;91170:153:0:o;90974:147::-;91047:6;91031:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;91079:34:0::1;-1:-1:-1::0;;91079:15:0;::::1;89124:2;91110;91079:15;:34::i;90779:149::-:0;90853:6;90837:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;90885:35:0::1;-1:-1:-1::0;;90885:15:0;::::1;89074:2;90917;90885:15;:35::i;90583:149::-:0;90657:6;90641:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;90689:35:0::1;-1:-1:-1::0;;90689:15:0;::::1;89024:1;90721:2;90689:15;:35::i;72329:132::-:0;72417:15;;;;72395:10;:38;72387:67;;;;-1:-1:-1;;;72387:67:0;;18081:2:1;72387:67:0;;;18063:21:1;18120:2;18100:18;;;18093:30;18159:18;18139;;;18132:46;18195:18;;72387:67:0;17879:340:1;81017:750:0;81102:11;;;;;;80621:1;;80605:13;;:1;:13;:::i;:::-;:17;;;;:::i;:::-;81131:4;:17;81123:46;;;;-1:-1:-1;;;81123:46:0;;19920:2:1;81123:46:0;;;19902:21:1;19959:2;19939:18;;;19932:30;19998:18;19978;;;19971:46;20034:18;;81123:46:0;19718:340:1;81123:46:0;81204:6;;81230:11;;;:18;;;81263:9;81258:319;80558:2;81278:1;:14;81258:319;;;81315:4;81322:1;81315:8;81328:1;81314:15;81310:101;;81367:5;81349;81362:1;81349:15;;;;;;;:::i;:::-;;:23;-1:-1:-1;;;;81017:750:0:o;81310:101::-;81459:5;81472:1;81459:15;;;;;;;:::i;:::-;;;81442:40;;;;;;17103:19:1;;;;17138:12;;17131:28;;;17175:12;;81442:40:0;;;;;;;;;;;;;81432:51;;81442:40;81432:51;;;;;-1:-1:-1;81506:1:0;81497:10;;;;81549:3;81258:319;;;-1:-1:-1;81747:13:0;;:::i;:::-;81077:690;81017:750;;:::o;13614:462::-;13725:15;;13767:11;13774:4;13767;:11;:::i;:::-;13752:26;;13893:4;13887:11;13881:4;13878:21;13875:66;;;-1:-1:-1;13926:1:0;13875:66;13964:4;13972:1;13964:9;13960:51;;-1:-1:-1;;13989:11:0;;;;;13960:51;-1:-1:-1;;12883:2:0;12879:27;;;12953:17;;;;12945:26;;;13017:17;13013:2;13009:26;;13614:462::o;17947:399::-;18086:7;18105:12;18120;18124:7;16204:3;16200:17;3488:26;16196:29;;15877:364;18120:12;18105:27;;;;18216:12;18220:7;18216:3;:12::i;:::-;18209:4;18193:13;18200:6;18193:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;18189:77;;;-1:-1:-1;;18244:11:0;;;;;18189:77;18283:13;18290:6;18283:4;:13;:::i;:::-;18276:20;;18313:26;18319:7;18313:26;;18328:4;18334;18313:5;:26::i;:::-;18306:33;17947:399;-1:-1:-1;;;;;;17947:399:0:o;27854:902::-;27932:15;-1:-1:-1;;8790:15:0;;;;27959:69;;;;-1:-1:-1;;;27959:69:0;;20454:2:1;27959:69:0;;;20436:21:1;20493:2;20473:18;;;20466:30;20532:34;20512:18;;;20505:62;20603:10;20583:18;;;20576:38;20631:19;;27959:69:0;20252:404:1;27959:69:0;28046:16;28054:7;28046;:16::i;:::-;28038:72;;;;-1:-1:-1;;;28038:72:0;;20863:2:1;28038:72:0;;;20845:21:1;20902:2;20882:18;;;20875:30;20941:34;20921:18;;;20914:62;21012:13;20992:18;;;20985:41;21043:19;;28038:72:0;20661:407:1;28038:72:0;28120:12;28135;28139:7;17310:2;17306:16;3488:26;17302:28;;17064:282;28135:12;28120:27;;;;28157:15;28175:12;28179:7;16204:3;16200:17;3488:26;16196:29;;15877:364;28175:12;28157:30;;;;28198:11;28319:4;28313:11;28306:18;;28406:7;28401:3;28398:16;28395:94;;;28446:4;28440;28433:18;28395:94;28661:4;28652:7;28646:4;28637:7;28634:1;28627:5;28616:50;28612:55;28697:52;28718:15;28725:7;15235:3;15231:17;;15024:268;28718:15;12879:27;12883:2;12879:27;;;;12953:17;;12945:26;;13017:17;;13013:2;13009:26;;12629:446;23273:290;23329:14;23355:12;23370;23374:7;16204:3;16200:17;3488:26;16196:29;;15877:364;23370:12;23355:27;;;;23392:12;23407;23411:7;17310:2;17306:16;3488:26;17302:28;;17064:282;23407:12;23392:27;;23526:21;;;;23273:290;-1:-1:-1;;;23273:290:0:o;48400:227::-;48478:7;48498:17;48517:18;48539:27;48550:4;48556:9;48539:10;:27::i;:::-;48497:69;;;;48576:18;48588:5;48576:11;:18::i;:::-;-1:-1:-1;48611:9:0;48400:227;-1:-1:-1;;;48400:227:0:o;19579:741::-;19725:17;19757:9;19770:15;19780:4;19770:9;:15::i;:::-;19754:31;;;19798:9;19811:15;19821:4;19811:9;:15::i;:::-;19795:31;;;19839:9;19852:17;19862:6;19852:9;:17::i;:::-;19836:33;;;19882:9;19895:17;19905:6;19895:9;:17::i;:::-;19879:33;;;20062:1;20124;20204;20266;19948:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19922:391;;19744:576;;;;19579:741;;;;;;:::o;68296:111::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;12803:2:1;62958:69:0;;;12785:21:1;12842:2;12822:18;;;12815:30;12881:34;12861:18;;;12854:62;12952:13;12932:18;;;12925:41;12983:19;;62958:69:0;12601:407:1;62958:69:0;68368:32:::1;67483:10:::0;68368:18:::1;:32::i;10461:132::-:0;10535:4;10577:9;10558:28;;:15;10565:7;15235:3;15231:17;;15024:268;10558:15;:28;;;;10461:132;-1:-1:-1;;;10461:132:0:o;5849:667::-;5903:13;;5959:2;5944:258;5967:2;5963:1;:6;;;5944:258;;;5987:11;6014:5;:1;6018;6014:5;:::i;:::-;6007:13;;:2;:13;;5987:34;;6044:14;6052:5;6044:7;:14::i;:::-;6035:23;;;;;;6076:1;:7;;6081:2;6076:7;6072:58;;6113:2;6103:12;;;;;6072:58;-1:-1:-1;6171:6:0;;5944:258;;;-1:-1:-1;6265:2:0;6250:260;6273:3;6269:1;:7;;;6250:260;;;6294:11;6321:5;:1;6325;6321:5;:::i;:::-;6314:13;;:2;:13;;6294:34;;6352:14;6360:5;6352:7;:14::i;:::-;6342:24;;;;;;6384:1;:6;;6389:1;6384:6;6380:58;;6421:2;6410:13;;;;;6380:58;-1:-1:-1;6479:6:0;;6250:260;;;;5849:667;;;:::o;17520:147::-;17573:7;17638:12;17642:7;17310:2;17306:16;3488:26;17302:28;;17064:282;17638:12;17623;17627:7;16204:3;16200:17;3488:26;16196:29;;15877:364;17623:12;:27;17616:34;;;;17520:147;;;:::o;9463:333::-;9520:8;9544:15;9551:7;15235:3;15231:17;;15024:268;9544:15;:31;;9563:12;9544:31;9540:74;;-1:-1:-1;9598:5:0;;9463:333;-1:-1:-1;9463:333:0:o;9540:74::-;9623:12;9638;9642:7;9638:3;:12::i;:::-;9773:4;9767:11;-1:-1:-1;9754:26:0;;9463:333;-1:-1:-1;;;9463:333:0:o;46335:1279::-;46416:7;46425:12;46646:9;:16;46666:2;46646:22;46642:966;;46935:4;46920:20;;46914:27;46984:4;46969:20;;46963:27;47041:4;47026:20;;47020:27;46684:9;47012:36;47082:25;47093:4;47012:36;46914:27;46963;47082:10;:25::i;:::-;47075:32;;;;;;;;;46642:966;47128:9;:16;47148:2;47128:22;47124:484;;47397:4;47382:20;;47376:27;47447:4;47432:20;;47426:27;47487:23;47498:4;47376:27;47426;47487:10;:23::i;:::-;47480:30;;;;;;;;47124:484;-1:-1:-1;47557:1:0;;-1:-1:-1;47561:35:0;47124:484;46335:1279;;;;;:::o;44640:631::-;44717:20;44708:5;:29;;;;;;;;:::i;:::-;;44704:561;;44640:631;:::o;44704:561::-;44813:29;44804:5;:38;;;;;;;;:::i;:::-;;44800:465;;44858:34;;-1:-1:-1;;;44858:34:0;;23175:2:1;44858:34:0;;;23157:21:1;23214:2;23194:18;;;23187:30;23253:26;23233:18;;;23226:54;23297:18;;44858:34:0;22973:348:1;44800:465:0;44922:35;44913:5;:44;;;;;;;;:::i;:::-;;44909:356;;44973:41;;-1:-1:-1;;;44973:41:0;;23528:2:1;44973:41:0;;;23510:21:1;23567:2;23547:18;;;23540:30;23606:33;23586:18;;;23579:61;23657:18;;44973:41:0;23326:355:1;44909:356:0;45044:30;45035:5;:39;;;;;;;;:::i;:::-;;45031:234;;45090:44;;-1:-1:-1;;;45090:44:0;;23888:2:1;45090:44:0;;;23870:21:1;23927:2;23907:18;;;23900:30;23966:34;23946:18;;;23939:62;24037:4;24017:18;;;24010:32;24059:19;;45090:44:0;23686:398:1;45031:234:0;45164:30;45155:5;:39;;;;;;;;:::i;:::-;;45151:114;;45210:44;;-1:-1:-1;;;45210:44:0;;24291:2:1;45210:44:0;;;24273:21:1;24330:2;24310:18;;;24303:30;24369:34;24349:18;;;24342:62;24440:4;24420:18;;;24413:32;24462:19;;45210:44:0;24089:398:1;5326:199:0;5376:14;5413:18;5429:1;5423:2;:7;;;;5413:9;:18::i;:::-;5402:29;;5455:13;;;;;;5467:1;5455:13;5489;5499:2;5489:9;:13::i;:::-;5478:24;;;;5326:199;-1:-1:-1;5326:199:0:o;49808:1603::-;49934:7;;50858:66;50845:79;;50841:161;;;-1:-1:-1;50956:1:0;;-1:-1:-1;50960:30:0;50940:51;;50841:161;51015:1;:7;;51020:2;51015:7;;:18;;;;;51026:1;:7;;51031:2;51026:7;;51015:18;51011:100;;;-1:-1:-1;51065:1:0;;-1:-1:-1;51069:30:0;51049:51;;51011:100;51222:24;;;51205:14;51222:24;;;;;;;;;24719:25:1;;;24792:4;24780:17;;24760:18;;;24753:45;;;;24814:18;;;24807:34;;;24857:18;;;24850:34;;;51222:24:0;;24691:19:1;;51222:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51222:24:0;;;;;;-1:-1:-1;;51260:20:0;;;51256:101;;51312:1;51316:29;51296:50;;;;;;;51256:101;51375:6;-1:-1:-1;51383:20:0;;-1:-1:-1;49808:1603:0;;;;;;;;:::o;48881:336::-;48991:7;;49049:66;49036:80;;48991:7;49142:25;49158:3;49143:18;;;49165:2;49142:25;:::i;:::-;49126:42;;49185:25;49196:4;49202:1;49205;49208;49185:10;:25::i;:::-;49178:32;;;;;;48881:336;;;;;;:::o;3761:1393::-;3813:10;3979:4;3974:9;;;;4025:15;;;;;4021:57;;-1:-1:-1;4063:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4021:57::-;4096:7;:15;;4107:4;4096:15;4092:57;;-1:-1:-1;4134:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4092:57::-;4167:7;:15;;4178:4;4167:15;4163:57;;-1:-1:-1;4205:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4163:57::-;4238:7;:15;;4249:4;4238:15;4234:57;;-1:-1:-1;4276:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4234:57::-;4309:7;:15;;4320:4;4309:15;4305:57;;-1:-1:-1;4347:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4305:57::-;4380:7;:15;;4391:4;4380:15;4376:57;;-1:-1:-1;4418:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4376:57::-;4451:7;:15;;4462:4;4451:15;4447:57;;-1:-1:-1;4489:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4447:57::-;4522:7;:15;;4533:4;4522:15;4518:57;;-1:-1:-1;4560:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4518:57::-;4593:7;:15;;4604:4;4593:15;4589:57;;-1:-1:-1;4631:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4589:57::-;4664:7;:15;;4675:4;4664:15;4660:57;;-1:-1:-1;4702:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4660:57::-;4735:7;:15;;4746:4;4735:15;4731:57;;-1:-1:-1;4773:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4731:57::-;4806:7;:15;;4817:4;4806:15;4802:57;;-1:-1:-1;4844:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4802:57::-;4877:7;:15;;4888:4;4877:15;4873:57;;-1:-1:-1;4915:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4873:57::-;4948:7;:15;;4959:4;4948:15;4944:57;;-1:-1:-1;4986:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4944:57::-;5019:7;:15;;5030:4;5019:15;5015:57;;-1:-1:-1;5057:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;5015:57::-;5090:7;:15;;5101:4;5090:15;5086:57;;-1:-1:-1;5128:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:184:1:-;248:77;245:1;238:88;345:4;342:1;335:15;369:4;366:1;359:15;385:777;427:5;480:3;473:4;465:6;461:17;457:27;447:55;;498:1;495;488:12;447:55;534:6;521:20;560:18;597:2;593;590:10;587:36;;;603:18;;:::i;:::-;737:2;731:9;799:4;791:13;;642:66;787:22;;;811:2;783:31;779:40;767:53;;;835:18;;;855:22;;;832:46;829:72;;;881:18;;:::i;:::-;921:10;917:2;910:22;956:2;948:6;941:18;1002:3;995:4;990:2;982:6;978:15;974:26;971:35;968:55;;;1019:1;1016;1009:12;968:55;1083:2;1076:4;1068:6;1064:17;1057:4;1049:6;1045:17;1032:54;1130:1;1123:4;1118:2;1110:6;1106:15;1102:26;1095:37;1150:6;1141:15;;;;;;385:777;;;;:::o;1167:320::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;1344:9;1331:23;1377:18;1369:6;1366:30;1363:50;;;1409:1;1406;1399:12;1363:50;1432:49;1473:7;1464:6;1453:9;1449:22;1432:49;:::i;1952:180::-;2011:6;2064:2;2052:9;2043:7;2039:23;2035:32;2032:52;;;2080:1;2077;2070:12;2032:52;-1:-1:-1;2103:23:1;;1952:180;-1:-1:-1;1952:180:1:o;2747:154::-;2833:42;2826:5;2822:54;2815:5;2812:65;2802:93;;2891:1;2888;2881:12;2906:247;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3073:9;3060:23;3092:31;3117:5;3092:31;:::i;3688:184::-;3740:77;3737:1;3730:88;3837:4;3834:1;3827:15;3861:4;3858:1;3851:15;3877:396;4020:2;4005:18;;4053:1;4042:13;;4032:201;;4089:77;4086:1;4079:88;4190:4;4187:1;4180:15;4218:4;4215:1;4208:15;4032:201;4242:25;;;3877:396;:::o;4808:163::-;4875:20;;4935:10;4924:22;;4914:33;;4904:61;;4961:1;4958;4951:12;4976:753;5087:6;5095;5103;5111;5119;5172:3;5160:9;5151:7;5147:23;5143:33;5140:53;;;5189:1;5186;5179:12;5140:53;5212:28;5230:9;5212:28;:::i;:::-;5202:38;;5287:2;5276:9;5272:18;5259:32;5249:42;;5310:37;5343:2;5332:9;5328:18;5310:37;:::i;:::-;5300:47;;5398:2;5387:9;5383:18;5370:32;5421:18;5462:2;5454:6;5451:14;5448:34;;;5478:1;5475;5468:12;5448:34;5501:49;5542:7;5533:6;5522:9;5518:22;5501:49;:::i;:::-;5491:59;;5603:3;5592:9;5588:19;5575:33;5559:49;;5633:2;5623:8;5620:16;5617:36;;;5649:1;5646;5639:12;5617:36;;5672:51;5715:7;5704:8;5693:9;5689:24;5672:51;:::i;:::-;5662:61;;;4976:753;;;;;;;;:::o;6264:184::-;6316:77;6313:1;6306:88;6413:4;6410:1;6403:15;6437:4;6434:1;6427:15;6453:258;6525:1;6535:113;6549:6;6546:1;6543:13;6535:113;;;6625:11;;;6619:18;6606:11;;;6599:39;6571:2;6564:10;6535:113;;;6666:6;6663:1;6660:13;6657:48;;;6701:1;6692:6;6687:3;6683:16;6676:27;6657:48;;6453:258;;;:::o;6716:316::-;6757:3;6795:5;6789:12;6822:6;6817:3;6810:19;6838:63;6894:6;6887:4;6882:3;6878:14;6871:4;6864:5;6860:16;6838:63;:::i;:::-;6946:2;6934:15;6951:66;6930:88;6921:98;;;;7021:4;6917:109;;6716:316;-1:-1:-1;;6716:316:1:o;7037:337::-;7224:42;7216:6;7212:55;7201:9;7194:74;7304:2;7299;7288:9;7284:18;7277:30;7175:4;7324:44;7364:2;7353:9;7349:18;7341:6;7324:44;:::i;7379:184::-;7431:77;7428:1;7421:88;7528:4;7525:1;7518:15;7552:4;7549:1;7542:15;7568:125;7608:4;7636:1;7633;7630:8;7627:34;;;7641:18;;:::i;:::-;-1:-1:-1;7678:9:1;;7568:125::o;8403:251::-;8473:6;8526:2;8514:9;8505:7;8501:23;8497:32;8494:52;;;8542:1;8539;8532:12;8494:52;8574:9;8568:16;8593:31;8618:5;8593:31;:::i;9939:228::-;9978:3;10006:10;10043:2;10040:1;10036:10;10073:2;10070:1;10066:10;10104:3;10100:2;10096:12;10091:3;10088:21;10085:47;;;10112:18;;:::i;:::-;10148:13;;9939:228;-1:-1:-1;;;;9939:228:1:o;10172:377::-;10365:2;10354:9;10347:21;10328:4;10391:44;10431:2;10420:9;10416:18;10408:6;10391:44;:::i;:::-;10483:9;10475:6;10471:22;10466:2;10455:9;10451:18;10444:50;10511:32;10536:6;10528;10511:32;:::i;13013:244::-;13052:3;13080:26;13133:2;13130:1;13126:10;13163:2;13160:1;13156:10;13194:3;13190:2;13186:12;13181:3;13178:21;13175:47;;;13202:18;;:::i;14071:238::-;14109:7;14149:4;14146:1;14142:12;14181:4;14178:1;14174:12;14241:3;14235:4;14231:14;14226:3;14223:23;14216:3;14209:11;14202:19;14198:49;14195:75;;;14250:18;;:::i;:::-;14290:13;;14071:238;-1:-1:-1;;;14071:238:1:o;14314:224::-;14353:3;14381:6;14414:2;14411:1;14407:10;14444:2;14441:1;14437:10;14475:3;14471:2;14467:12;14462:3;14459:21;14456:47;;;14483:18;;:::i;14543:1073::-;14868:3;14896:66;15005:2;14996:6;14991:3;14987:16;14983:25;14978:3;14971:38;15060:2;15051:6;15046:3;15042:16;15038:25;15034:1;15029:3;15025:11;15018:46;15115:2;15106:6;15101:3;15097:16;15093:25;15089:1;15084:3;15080:11;15073:46;15170:2;15161:6;15156:3;15152:16;15148:25;15144:1;15139:3;15135:11;15128:46;;15203:6;15197:13;15219:61;15273:6;15269:1;15264:3;15260:11;15253:4;15245:6;15241:17;15219:61;:::i;:::-;15340:13;;15299:16;;;;15362:62;15340:13;15411:1;15403:10;;15396:4;15384:17;;15362:62;:::i;:::-;15485:13;;15443:17;;;15507:62;15485:13;15556:1;15548:10;;15541:4;15529:17;;15507:62;:::i;:::-;15589:17;15608:1;15585:25;;14543:1073;-1:-1:-1;;;;;;;;;14543:1073:1:o;15962:195::-;16000:4;16037;16034:1;16030:12;16069:4;16066:1;16062:12;16094:3;16089;16086:12;16083:38;;;16101:18;;:::i;:::-;16138:13;;;15962:195;-1:-1:-1;;;15962:195:1:o;16162:128::-;16202:3;16233:1;16229:6;16226:1;16223:13;16220:39;;;16239:18;;:::i;:::-;-1:-1:-1;16275:9:1;;16162:128::o;16295:219::-;16444:2;16433:9;16426:21;16407:4;16464:44;16504:2;16493:9;16489:18;16481:6;16464:44;:::i;18224:482::-;18313:1;18356:5;18313:1;18370:330;18391:7;18381:8;18378:21;18370:330;;;18510:4;18442:66;18438:77;18432:4;18429:87;18426:113;;;18519:18;;:::i;:::-;18569:7;18559:8;18555:22;18552:55;;;18589:16;;;;18552:55;18668:22;;;;18628:15;;;;18370:330;;;18374:3;18224:482;;;;;:::o;18711:866::-;18760:5;18790:8;18780:80;;-1:-1:-1;18831:1:1;18845:5;;18780:80;18879:4;18869:76;;-1:-1:-1;18916:1:1;18930:5;;18869:76;18961:4;18979:1;18974:59;;;;19047:1;19042:130;;;;18954:218;;18974:59;19004:1;18995:10;;19018:5;;;19042:130;19079:3;19069:8;19066:17;19063:43;;;19086:18;;:::i;:::-;-1:-1:-1;;19142:1:1;19128:16;;19157:5;;18954:218;;19256:2;19246:8;19243:16;19237:3;19231:4;19228:13;19224:36;19218:2;19208:8;19205:16;19200:2;19194:4;19191:12;19187:35;19184:77;19181:159;;;-1:-1:-1;19293:19:1;;;19325:5;;19181:159;19372:34;19397:8;19391:4;19372:34;:::i;:::-;19502:6;19434:66;19430:79;19421:7;19418:92;19415:118;;;19513:18;;:::i;19582:131::-;19642:5;19671:36;19698:8;19692:4;19671:36;:::i;20063:184::-;20115:77;20112:1;20105:88;20212:4;20209:1;20202:15;20236:4;20233:1;20226:15;21577:1391;22299:34;22287:47;;22364:23;22359:2;22350:12;;22343:45;22407:66;22511:3;22507:16;;;22503:25;;22498:2;22489:12;;22482:47;22548:17;22590:2;22581:12;;22574:24;;;22632:16;;;22628:25;;22623:2;22614:12;;22607:47;22684:34;22679:2;22670:12;;22663:56;22750:3;22744;22735:13;;22728:26;22789:16;;;22785:25;;22779:3;22770:13;;22763:48;22836:3;22827:13;;22820:25;22880:16;;;22876:25;22870:3;22861:13;;22854:48;21535:3;22957;22948:13;;21523:16;-1:-1:-1;21555:11:1;;;22918:44;21458:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"leafIndex","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"destinationAndNonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"tips","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Dispatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"ImproperAttestation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updaterManager","type":"address"}],"name":"NewUpdaterManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"address","name":"reporter","type":"address"}],"name":"UpdaterSlashed","type":"event"},{"inputs":[],"name":"MAX_MESSAGE_BODY_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipientAddress","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"improperAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUpdaterManager","name":"_updaterManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterManager","type":"address"}],"name":"setUpdaterManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Home.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"suggestUpdate","outputs":[{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updaterManager","outputs":[{"internalType":"contract IUpdaterManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"notice":"Emitted when a new message is dispatched via Nomad"},"ImproperAttestation(address,bytes)":{"notice":"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state"},"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"NewUpdaterManager(address)":{"notice":"Emitted when the UpdaterManager contract is changed"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"},"UpdaterSlashed(address,address)":{"notice":"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)"}},"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"notice":"Dispatch the message to the destination domain \u0026 recipient"},"improperAttestation(bytes)":{"notice":"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation."},"root()":{"notice":"Calculates and returns tree's current root"},"setUpdater(address)":{"notice":"Set a new Updater"},"setUpdaterManager(address)":{"notice":"Set a new UpdaterManager contract"},"suggestUpdate()":{"notice":"Suggest an update for the Updater to sign and submit."}},"notice":"Accepts messages to be dispatched to remote chains, constructs a Merkle tree of the messages, and accepts signatures from a bonded Updater which notarize the Merkle tree roots. Accepts submissions of fraudulent signatures by the Updater and slashes the Updater in this case.","version":1},"developerDoc":{"author":"Illusory Systems Inc.","events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"params":{"destinationAndNonce":"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)","leafIndex":"Index of message's leaf in merkle tree","message":"Raw bytes of message","messageHash":"Hash of message; the leaf inserted to the Merkle tree for the message","tips":"Tips paid for the remote off-chain agents"}},"ImproperAttestation(address,bytes)":{"params":{"attestation":"Attestation data and signature","updater":"Updater who signed improper attestation"}},"NewUpdaterManager(address)":{"params":{"updaterManager":"The address of the new updaterManager"}},"UpdaterSlashed(address,address)":{"params":{"reporter":"The address of the entity that reported the updater misbehavior","updater":"The address of the updater"}}},"kind":"dev","methods":{"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"details":"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.","params":{"_destinationDomain":"Domain of destination chain","_messageBody":"Raw bytes content of message","_recipientAddress":"Address of recipient on destination chain as bytes32"}},"improperAttestation(bytes)":{"details":"Reverts (and doesn't slash updater) if signature is invalid or update not current","params":{"_attestation":"Attestation data and signature"},"returns":{"_0":"TRUE if update was an Improper Attestation (implying Updater was slashed)"}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setUpdater(address)":{"details":"To be set when rotating Updater after Fraud","params":{"_updater":"the new Updater"}},"setUpdaterManager(address)":{"details":"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation","params":{"_updaterManager":"the new UpdaterManager contract"}},"suggestUpdate()":{"details":"If no messages have been sent, null bytes returned for both","returns":{"_nonce":"Current nonce","_root":"Current merkle root"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"title":"Home","version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum Home.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Illusory Systems Inc.\",\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"params\":{\"destinationAndNonce\":\"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\",\"leafIndex\":\"Index of message's leaf in merkle tree\",\"message\":\"Raw bytes of message\",\"messageHash\":\"Hash of message; the leaf inserted to the Merkle tree for the message\",\"tips\":\"Tips paid for the remote off-chain agents\"}},\"ImproperAttestation(address,bytes)\":{\"params\":{\"attestation\":\"Attestation data and signature\",\"updater\":\"Updater who signed improper attestation\"}},\"NewUpdaterManager(address)\":{\"params\":{\"updaterManager\":\"The address of the new updaterManager\"}},\"UpdaterSlashed(address,address)\":{\"params\":{\"reporter\":\"The address of the entity that reported the updater misbehavior\",\"updater\":\"The address of the updater\"}}},\"kind\":\"dev\",\"methods\":{\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"details\":\"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.\",\"params\":{\"_destinationDomain\":\"Domain of destination chain\",\"_messageBody\":\"Raw bytes content of message\",\"_recipientAddress\":\"Address of recipient on destination chain as bytes32\"}},\"improperAttestation(bytes)\":{\"details\":\"Reverts (and doesn't slash updater) if signature is invalid or update not current\",\"params\":{\"_attestation\":\"Attestation data and signature\"},\"returns\":{\"_0\":\"TRUE if update was an Improper Attestation (implying Updater was slashed)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setUpdater(address)\":{\"details\":\"To be set when rotating Updater after Fraud\",\"params\":{\"_updater\":\"the new Updater\"}},\"setUpdaterManager(address)\":{\"details\":\"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\",\"params\":{\"_updaterManager\":\"the new UpdaterManager contract\"}},\"suggestUpdate()\":{\"details\":\"If no messages have been sent, null bytes returned for both\",\"returns\":{\"_nonce\":\"Current nonce\",\"_root\":\"Current merkle root\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"Home\",\"version\":1},\"userdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"notice\":\"Emitted when a new message is dispatched via Nomad\"},\"ImproperAttestation(address,bytes)\":{\"notice\":\"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state\"},\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"NewUpdaterManager(address)\":{\"notice\":\"Emitted when the UpdaterManager contract is changed\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"},\"UpdaterSlashed(address,address)\":{\"notice\":\"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)\"}},\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Dispatch the message to the destination domain \u0026 recipient\"},\"improperAttestation(bytes)\":{\"notice\":\"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation.\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"},\"setUpdater(address)\":{\"notice\":\"Set a new Updater\"},\"setUpdaterManager(address)\":{\"notice\":\"Set a new UpdaterManager contract\"},\"suggestUpdate()\":{\"notice\":\"Suggest an update for the Updater to sign and submit.\"}},\"notice\":\"Accepts messages to be dispatched to remote chains, constructs a Merkle tree of the messages, and accepts signatures from a bonded Updater which notarize the Merkle tree roots. Accepts submissions of fraudulent signatures by the Updater and slashes the Updater in this case.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Home\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{"MAX_MESSAGE_BODY_BYTES()":"522ae002","VERSION()":"ffa1ad74","count()":"06661abd","dispatch(uint32,bytes32,uint32,bytes,bytes)":"f7560e40","historicalRoots(uint256)":"7ea97f40","improperAttestation(bytes)":"0afe7f90","initialize(address)":"c4d66de8","localDomain()":"8d3638f4","nonce()":"affed0e0","owner()":"8da5cb5b","renounceOwnership()":"715018a6","root()":"ebf0c717","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","setUpdaterManager(address)":"9776120e","state()":"c19d93fb","suggestUpdate()":"36e104de","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","tree()":"fd54b228","updater()":"df034cd0","updaterManager()":"9df6c8e1"}},"solidity/Home.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/Home.sol:IUpdaterManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"address payable","name":"_reporter","type":"address"}],"name":"slashUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"IUpdaterManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{"slashUpdater(address)":"5b3c2cbf","updater()":"df034cd0"}},"solidity/Home.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b737e947247f0f89898c3566b3afaad49da119f05331b4bec3e9032c64970f3264736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b737e947247f0f89898c3566b3afaad49da119f05331b4bec3e9032c64970f3264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80495:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;80495:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"80495:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:MerkleTreeManager":{"code":"0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207896510a8d1ce75be68644ea5051254561e0e79b05bc30e55cbe0222d59335a164736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207896510a8d1ce75be68644ea5051254561e0e79b05bc30e55cbe0222d59335a164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"95745:968:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"95745:968:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96350:81;96414:10;;96350:81;;;160:25:1;;;148:2;133:18;96350:81:0;;;;;;;95894:32;;;;;;:::i;:::-;;:::i;96166:81::-;;;:::i;95862:26::-;;;;;;;95894:32;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;95894:32:0;:::o;96166:81::-;96203:7;96229:11;:4;:9;:11::i;:::-;96222:18;;96166:81;:::o;82634:122::-;82691:7;82717:32;82729:5;82736:12;:10;:12::i;:::-;82717:11;:32::i;:::-;82710:39;82634:122;-1:-1:-1;;82634:122:0:o;82874:964::-;82919:34;;:::i;:::-;82978:3;82965:16;;83004:3;82965:10;82991;;:16;83030:3;83017:10;;;:16;83056:3;83043:10;;;:16;83082:3;83069:10;;;:16;83108:3;83095:10;;;:16;83134:3;83121:10;;;:16;83160:3;83147:10;;;:16;83186:3;83173:10;;;:16;83212:3;83199:10;;;:16;83239:4;83225:11;;;:18;83267:4;83253:11;;;:18;83295:4;83281:11;;;:18;83323:4;83309:11;;;:18;83351:4;83337:11;;;:18;83379:4;83365:11;;;:18;83407:4;83393:11;;;:18;83435:4;83421:11;;;:18;83463:4;83449:11;;;:18;83491:4;83477:11;;;:18;83519:4;83505:11;;;:18;83547:4;83533:11;;;:18;83575:4;83561:11;;;:18;83603:4;83589:11;;;:18;83631:4;83617:11;;;:18;83659:4;83645:11;;;:18;83687:4;83673:11;;;:18;83715:4;83701:11;;;:18;83743:4;83729:11;;;:18;83771:4;83757:11;;;:18;83799:4;83785:11;;;:18;83827:4;83813:11;;;:18;82965:7;82874:964::o;81978:589::-;82151:11;;;;82102:16;;;82173:388;80558:2;82193:1;:14;82173:388;;;82259:4;82244:11;;;82243:20;;;82281:12;;;82277:215;;82351:5;82364:1;82351:15;;;;;;;:::i;:::-;;;82334:43;;;;;;909:19:1;;;;944:12;;937:28;;;981:12;;82334:43:0;;;;;;;;;;;;82324:54;;;;;;82313:65;;82277:215;;;82455:8;82465:7;82473:1;82465:10;;;;;;;:::i;:::-;;;;;82438:38;;;;;;;;909:19:1;;;953:2;944:12;;937:28;990:2;981:12;;752:247;82438:38:0;;;;;;;;;;;;;82428:49;;;;;;82417:60;;82277:215;-1:-1:-1;82533:3:0;;82173:388;;;;82124:443;81978:589;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;563:184::-;615:77;612:1;605:88;712:4;709:1;702:15;736:4;733:1;726:15","abiDefinition":[{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"root()":{"notice":"Calculates and returns tree's current root"}},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"MerkleTreeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{"count()":"06661abd","historicalRoots(uint256)":"7ea97f40","root()":"ebf0c717","tree()":"fd54b228"}},"solidity/Home.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ac66f819cd7f6b8f15774cd2f663f8d36a1e3c457c46e5f44363c1711e30dda364736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ac66f819cd7f6b8f15774cd2f663f8d36a1e3c457c46e5f44363c1711e30dda364736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"34204:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;34204:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"34204:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/Home.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220958f158d4121a9ee7472bf1af1ba99d418ed03bdad597d5eeeb22ead10fd1ad064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220958f158d4121a9ee7472bf1af1ba99d418ed03bdad597d5eeeb22ead10fd1ad064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"42574:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;42574:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"42574:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212203f6845479810340a467d2cde8987224b4b6c2285b5a69de39862e19c7cf8319064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212203f6845479810340a467d2cde8987224b4b6c2285b5a69de39862e19c7cf8319064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"91516:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;91516:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"91516:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f4b0c5da8d8500be15e8a6f6d90648b0986dc65efa9dc5ee5f3d1e21baacc75c64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f4b0c5da8d8500be15e8a6f6d90648b0986dc65efa9dc5ee5f3d1e21baacc75c64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"88515:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;88515:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"88515:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f48e7743f5652bcabb07b0c6a811bb87e95c3ee03c5f58210c9b4c41de216c3564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f48e7743f5652bcabb07b0c6a811bb87e95c3ee03c5f58210c9b4c41de216c3564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33092:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33092:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33092:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212209f79b827606424be1f696b438c892aaa1ea2217c087a982a1bc8e2c068d4334264736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212209f79b827606424be1f696b438c892aaa1ea2217c087a982a1bc8e2c068d4334264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"844:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;844:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"844:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;3357:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;3357:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/Home.sol:UpdaterStorage":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"}},"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"NewUpdater(address,address)":{"params":{"newUpdater":"The address of the new updater","oldUpdater":"The address of the old updater"}},"Update(uint32,uint32,bytes32,bytes)":{"params":{"homeDomain":"Domain of home contract","nonce":"Nonce of new merkle root","root":"New merkle root","signature":"Updater's signature on `homeDomain`, `nonce` and `root`"}}},"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"params\":{\"newUpdater\":\"The address of the new updater\",\"oldUpdater\":\"The address of the old updater\"}},\"Update(uint32,uint32,bytes32,bytes)\":{\"params\":{\"homeDomain\":\"Domain of home contract\",\"nonce\":\"Nonce of new merkle root\",\"root\":\"New merkle root\",\"signature\":\"Updater's signature on `homeDomain`, `nonce` and `root`\"}}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"UpdaterStorage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/Home.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220604fcf8af2331bdc47a138d33f1aff2296b23b6ac6241b3700915f6276da443f64736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220604fcf8af2331bdc47a138d33f1aff2296b23b6ac6241b3700915f6276da443f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50:33;;82:1;50:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;50:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0xed356677359659a5865c15450a2d0fcaebc467d37af2f99ec212ef8c3dea1cff\",\"urls\":[\"bzz-raw://c45076b873c9db852c281414e428d6008656d4952e251da5afb3d76858373319\",\"dweb:/ipfs/QmemtMN8Gn3VYx4SawenGBJSgKZ5TTL98gVqe7J9SNGQVa\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file +{"solidity/Home.sol:AbstractGuardRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"AbstractGuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:AbstractNotaryRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"AbstractNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Address":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a31bdd6619397ba0f7531e5b3cb1bcb23234fe47d1c82e9187a5205ef5b1d88164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a31bdd6619397ba0f7531e5b3cb1bcb23234fe47d1c82e9187a5205ef5b1d88164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"117245:8061:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;117245:8061:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"117245:8061:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Address\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220372f28fd136caf4eb520ca25524adcfa0a45c183eba12437cc26a498015a2e9464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220372f28fd136caf4eb520ca25524adcfa0a45c183eba12437cc26a498015a2e9464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"94547:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;94547:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"94547:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c94353cfcbcddb3ecb41e58c1ba984e4c5ffe990405fea301773c4f326bd14e064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c94353cfcbcddb3ecb41e58c1ba984e4c5ffe990405fea301773c4f326bd14e064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32332:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32332:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32332:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122072a0ed4f918458a0cf4c1dcac03516b8775621101ee2182a92af4428b0b4482564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122072a0ed4f918458a0cf4c1dcac03516b8775621101ee2182a92af4428b0b4482564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"46455:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;46455:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"46455:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:DomainNotaryRegistry":{"code":"0x60a060405234801561001057600080fd5b506040516102e73803806102e783398101604081905261002f9161003d565b63ffffffff1660805261006a565b60006020828403121561004f57600080fd5b815163ffffffff8116811461006357600080fd5b9392505050565b608051610265610082600039600050506102656000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220f0358fecc3302bdb6fbcb411209862a283459b9383dac3ee9b6f7fa9a32dfffe64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220f0358fecc3302bdb6fbcb411209862a283459b9383dac3ee9b6f7fa9a32dfffe64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"59557:5230:0:-:0;;;62646:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62691:30;;;;59557:5230;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;59557:5230:0;;;;;;;;;;;","srcMapRuntime":"59557:5230:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63501:99;;;:::i;:::-;;;160:25:1;;;148:2;133:18;63501:99:0;;;;;;;;63274:105;;;:::i;:::-;;;;;;;:::i;63385:110::-;;;;;;:::i;:::-;;:::i;:::-;;;1243:42:1;1231:55;;;1213:74;;1201:2;1186:18;63385:110:0;1067:226:1;63501:99:0;63550:7;63576:17;:8;:15;:17::i;:::-;63569:24;;63501:99;:::o;63274:105::-;63320:16;63355:17;:8;:15;:17::i;63385:110::-;63443:7;63469:19;63443:7;63481:6;63469:11;:19::i;:::-;63462:26;63385:110;-1:-1:-1;;63385:110:0:o;55788:115::-;55851:7;55877:19;55885:3;51403:18;;51321:107;56941:257;57004:16;57032:22;57057:19;57065:3;57057:7;:19::i;:::-;57032:44;56941:257;-1:-1:-1;;;56941:257:0:o;56245:156::-;56319:7;56369:22;56373:3;56385:5;56369:3;:22::i;52428:109::-;52484:16;52519:3;:11;;52512:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52428:109;;;:::o;51770:118::-;51837:7;51863:3;:11;;51875:5;51863:18;;;;;;;;:::i;:::-;;;;;;;;;51856:25;;51770:118;;;;:::o;196:681:1:-;367:2;419:21;;;489:13;;392:18;;;511:22;;;338:4;;367:2;590:15;;;;564:2;549:18;;;338:4;633:218;647:6;644:1;641:13;633:218;;;712:13;;727:42;708:62;696:75;;826:15;;;;791:12;;;;669:1;662:9;633:218;;;-1:-1:-1;868:3:1;;196:681;-1:-1:-1;;;;;;196:681:1:o;882:180::-;941:6;994:2;982:9;973:7;969:23;965:32;962:52;;;1010:1;1007;1000:12;962:52;-1:-1:-1;1033:23:1;;882:180;-1:-1:-1;882:180:1:o;1298:184::-;1350:77;1347:1;1340:88;1447:4;1444:1;1437:15;1471:4;1468:1;1461:15","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_trackedDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryRemoved","type":"event"},{"inputs":[],"name":"allNotaries","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNotary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notariesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_trackedDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"DomainNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"allNotaries()":"9817e315","getNotary(uint256)":"c07dc7f5","notariesAmount()":"8e62e9ef"}},"solidity/Home.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202a58c00b5b08e7ab17206accdfa1a4ab9495ccfc6cb68f21a1d8091082e371f564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202a58c00b5b08e7ab17206accdfa1a4ab9495ccfc6cb68f21a1d8091082e371f564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"37529:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;37529:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"37529:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:EnumerableSet":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122001368ad527ededa5a6ac32f775715bd9e79d3f2e5933ee0aac3483702713b4c964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122001368ad527ededa5a6ac32f775715bd9e79d3f2e5933ee0aac3483702713b4c964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"48187:11368:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;48187:11368:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"48187:11368:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"EnumerableSet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:GuardRegistry":{"code":"0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220474cfa44d374c0ec38027aaecbcb0f008ff0a37aa575a9a55a61b9b3339b42f264736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220474cfa44d374c0ec38027aaecbcb0f008ff0a37aa575a9a55a61b9b3339b42f264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"65137:3868:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"65137:3868:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67835:95;;;:::i;:::-;;;160:25:1;;;148:2;133:18;67835:95:0;;;;;;;;67722:107;;;;;;:::i;:::-;;:::i;:::-;;;557:42:1;545:55;;;527:74;;515:2;500:18;67722:107:0;381:226:1;67615:101:0;;;:::i;:::-;;;;;;;:::i;67835:95::-;67882:7;67908:15;:6;:13;:15::i;:::-;67901:22;;67835:95;:::o;67722:107::-;67779:7;67805:17;67779:7;67815:6;67805:9;:17::i;:::-;67798:24;67722:107;-1:-1:-1;;67722:107:0:o;67615:101::-;67659:16;67694:15;:6;:13;:15::i;55788:115::-;55851:7;55877:19;55885:3;51403:18;;51321:107;56245:156;56319:7;56369:22;56373:3;56385:5;56369:3;:22::i;:::-;56361:31;56245:156;-1:-1:-1;;;56245:156:0:o;56941:257::-;57004:16;57032:22;57057:19;57065:3;57057:7;:19::i;51770:118::-;51837:7;51863:3;:11;;51875:5;51863:18;;;;;;;;:::i;:::-;;;;;;;;;51856:25;;51770:118;;;;:::o;52428:109::-;52484:16;52519:3;:11;;52512:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52428:109;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;612:681::-;783:2;835:21;;;905:13;;808:18;;;927:22;;;754:4;;783:2;1006:15;;;;980:2;965:18;;;754:4;1049:218;1063:6;1060:1;1057:13;1049:218;;;1128:13;;1143:42;1124:62;1112:75;;1242:15;;;;1207:12;;;;1085:1;1078:9;1049:218;;;-1:-1:-1;1284:3:1;;612:681;-1:-1:-1;;;;;;612:681:1:o;1298:184::-;1350:77;1347:1;1340:88;1447:4;1444:1;1437:15;1471:4;1468:1;1461:15","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"GuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"allGuards()":"9fe03fa2","getGuard(uint256)":"629ddf69","guardsAmount()":"246c2449"}},"solidity/Home.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122021d5f30e948fc5f90cf8579074c0159128bc49f9984434488c3483606aaf88d164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122021d5f30e948fc5f90cf8579074c0159128bc49f9984434488c3483606aaf88d164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"78143:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;78143:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"78143:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Home":{"code":"0x60c06040523480156200001157600080fd5b50604051620038c7380380620038c7833981016040819052620000349162000048565b63ffffffff16608081905260a05262000077565b6000602082840312156200005b57600080fd5b815163ffffffff811681146200007057600080fd5b9392505050565b60805160a051613823620000a460003960006118a70152600081816102ef0152610ea501526138236000f3fe6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea2646970667358221220f4ec54b2d176fcf05d50423158ec4b3391eae01e44861c6f3c163df8aba5512664736f6c634300080d0033","runtime-code":"0x6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea2646970667358221220f4ec54b2d176fcf05d50423158ec4b3391eae01e44861c6f3c163df8aba5512664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"125761:12373:0:-:0;;;128815:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113030:26;;;;;;62691:30;;125761:12373;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;125761:12373:0;;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"125761:12373:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116729:81;;;;;;;;;;-1:-1:-1;116793:10:0;;116729:81;;;160:25:1;;;148:2;133:18;116729:81:0;;;;;;;;134662:780;;;;;;;;;;-1:-1:-1;134662:780:0;;;;;:::i;:::-;;:::i;:::-;;;1657:14:1;;1650:22;1632:41;;1620:2;1605:18;134662:780:0;1492:187:1;67835:95:0;;;;;;;;;;;;;:::i;133111:257::-;;;;;;;;;;;;;:::i;:::-;;;;1886:10:1;1874:23;;;1856:42;;1929:2;1914:18;;1907:34;;;;1829:18;133111:257:0;1684:263:1;126667:58:0;;;;;;;;;;;;126716:9;126667:58;;67722:107;;;;;;;;;;-1:-1:-1;67722:107:0;;;;;:::i;:::-;;:::i;:::-;;;2313:42:1;2301:55;;;2283:74;;2271:2;2256:18;67722:107:0;2137:226:1;115346:57:0;;;;;;;;;;;;;:::i;:::-;;116273:32;;;;;;;;;;-1:-1:-1;116273:32:0;;;;;:::i;:::-;;:::i;111819:35::-;;;;;;;;;;;;;;;;;;2724:10:1;2712:23;;;2694:42;;2682:2;2667:18;111819:35:0;2550:192:1;109502:85:0;;;;;;;;;;-1:-1:-1;109574:6:0;;;;109502:85;;63501:99;;;;;;;;;;;;;:::i;130752:140::-;;;;;;;;;;-1:-1:-1;130752:140:0;;;;;:::i;:::-;;:::i;63274:105::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;130080:253::-;;;;;;;;;;-1:-1:-1;130080:253:0;;;;;:::i;:::-;;:::i;126940:37::-;;;;;;;;;;-1:-1:-1;126940:37:0;;;;;;;;;;;67615:101;;;;;;;;;;;;;:::i;126844:19::-;;;;;;;;;;-1:-1:-1;126844:19:0;;;;;;;;115020:133;;;;;;;;;;-1:-1:-1;115020:133:0;;;;;:::i;:::-;;:::i;63385:110::-;;;;;;;;;;-1:-1:-1;63385:110:0;;;;;:::i;:::-;;:::i;127016:19::-;;;;;;;;;;-1:-1:-1;127016:19:0;;;;;;;;;;;;;;;;;;:::i;129026:354::-;;;;;;;;;;-1:-1:-1;129026:354:0;;;;;:::i;:::-;;:::i;112401:39::-;;;;;;;;;;-1:-1:-1;112401:39:0;;;;;;;;116545:81;;;;;;;;;;;;;:::i;110384:198::-;;;;;;;;;;-1:-1:-1;110384:198:0;;;;;:::i;:::-;;:::i;131398:1473::-;;;;;;:::i;:::-;;:::i;116241:26::-;;;;;;;;;;-1:-1:-1;116241:26:0;;;;;;50:33;;;;;;;;;;;;82:1;50:33;;;;;6596:4:1;6584:17;;;6566:36;;6554:2;6539:18;50:33:0;6424:184:1;134662:780:0;134744:4;129798:13;129789:5;;;;;;;:22;;;;;;;;:::i;:::-;;129781:47;;;;-1:-1:-1;;;129781:47:0;;6815:2:1;129781:47:0;;;6797:21:1;6854:2;6834:18;;;6827:30;6893:14;6873:18;;;6866:42;6925:18;;129781:47:0;;;;;;;;;134815:15:::1;134832:13:::0;134849:30:::1;134866:12;134849:16;:30::i;:::-;134814:65;;;;134889:13;134905:24;:5;:22;;;;:24::i;:::-;134889:40:::0;-1:-1:-1;134939:13:0::1;134955:23;-1:-1:-1::0;;134955:21:0;::::1;;:23::i;:::-;135063:15;:22:::0;134939:39;;-1:-1:-1;135054:31:0::1;::::0;::::1;;135050:284;;;135114:15;135130:6;135114:23;;;;;;;;;;:::i;:::-;;;;;;;;;135105:5;:32:::0;135101:139:::1;;-1:-1:-1::0;135220:5:0::1;::::0;134662:780;-1:-1:-1;;;;;134662:780:0:o;135101:139::-:1;135343:14;135349:7;135343:5;:14::i;:::-;135372:42;135392:7;135401:12;135372:42;;;;;;;:::i;:::-;;;;;;;;135431:4;135424:11;;;;;;129838:1;134662:780:::0;;;:::o;67835:95::-;67882:7;67908:15;:6;:13;:15::i;:::-;67901:22;;67835:95;:::o;133111:257::-;133216:15;:22;133159:13;;;;133252:11;;133248:114;;133295:10;133304:1;133295:6;:10;:::i;:::-;133279:27;;133328:15;133344:6;133328:23;;;;;;;;;;:::i;:::-;;;;;;;;;133320:31;;133248:114;133189:179;133111:257;;:::o;67722:107::-;67779:7;67805:17;:6;67815;67805:9;:17::i;:::-;67798:24;67722:107;-1:-1:-1;;67722:107:0:o;115346:57::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;8590:2:1;109706:68:0;;;8572:21:1;;;8609:18;;;8602:30;8668:34;8648:18;;;8641:62;8720:18;;109706:68:0;8388:356:1;109706:68:0;115346:57::o;116273:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116273:32:0;:::o;63501:99::-;63550:7;63576:17;:8;:15;:17::i;130752:140::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;8590:2:1;109706:68:0;;;8572:21:1;;;8609:18;;;8602:30;8668:34;8648:18;;;8641:62;8720:18;;109706:68:0;8388:356:1;109706:68:0;130833:52:::1;130868:15;130833:18;:52::i;:::-;130752:140:::0;:::o;63274:105::-;63320:16;63355:17;:8;:15;:17::i;130080:253::-;129594:14;;;;;;;129572:10;:37;129564:65;;;;-1:-1:-1;;;129564:65:0;;8951:2:1;129564:65:0;;;8933:21:1;8990:2;8970:18;;;8963:30;9029:17;9009:18;;;9002:45;9064:18;;129564:65:0;8749:339:1;129564:65:0;130190:20:::1;130201:8;130190:10;:20::i;:::-;-1:-1:-1::0;;130305:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;130080:253::o;67615:101::-;67659:16;67694:15;:6;:13;:15::i;115020:133::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;8590:2:1;109706:68:0;;;8572:21:1;;;8609:18;;;8602:30;8668:34;8648:18;;;8641:62;8720:18;;109706:68:0;8388:356:1;109706:68:0;115112:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;115020:133::o;63385:110::-;63443:7;63469:19;:8;63481:6;63469:11;:19::i;129026:354::-;104682:19;104704:25;104727:1;104704:22;:25::i;:::-;104682:47;;104743:14;104739:65;;;104773:13;:20;;;;;;;;104739:65;129108:29:::1;:27;:29::i;:::-;129147:35;129166:15;129147:18;:35::i;:::-;129192:36;129203:14;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;129192:10;:36::i;:::-;-1:-1:-1::0;129238:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;129340:15:::1;:33:::0;;-1:-1:-1;129340:33:0;::::1;::::0;;-1:-1:-1;129340:33:0;;;;::::1;::::0;104824:99;;;;104858:13;:21;;;;;;104898:14;;-1:-1:-1;6566:36:1;;104898:14:0;;6554:2:1;6539:18;104898:14:0;;;;;;;104824:99;104672:257;129026:354;:::o;116545:81::-;116582:7;116608:11;:4;:9;:11::i;110384:198::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;8590:2:1;109706:68:0;;;8572:21:1;;;8609:18;;;8602:30;8668:34;8648:18;;;8641:62;8720:18;;109706:68:0;8388:356:1;109706:68:0;110472:22:::1;::::0;::::1;110464:73;;;::::0;-1:-1:-1;;;110464:73:0;;9750:2:1;110464:73:0::1;::::0;::::1;9732:21:1::0;9789:2;9769:18;;;9762:30;9828:34;9808:18;;;9801:62;9899:8;9879:18;;;9872:36;9925:19;;110464:73:0::1;9548:402:1::0;110464:73:0::1;110547:28;110566:8;110547:18;:28::i;131398:1473::-:0;129798:13;129789:5;;;;;;;:22;;;;;;;;:::i;:::-;;129781:47;;;;-1:-1:-1;;;129781:47:0;;6815:2:1;129781:47:0;;;6797:21:1;6854:2;6834:18;;;6827:30;6893:14;6873:18;;;6866:42;6925:18;;129781:47:0;6613:336:1;129781:47:0;126716:9:::1;131635:12;:19;:45;;131627:70;;;::::0;-1:-1:-1;;;131627:70:0;;10157:2:1;131627:70:0::1;::::0;::::1;10139:21:1::0;10196:2;10176:18;;;10169:30;10235:14;10215:18;;;10208:42;10267:18;;131627:70:0::1;9955:336:1::0;131627:70:0::1;131747:9;131715:28;:16;:5;:14;:16::i;:::-;-1:-1:-1::0;;131715:26:0::1;;:28::i;:::-;:41;;;131707:59;;;::::0;-1:-1:-1;;;131707:59:0;;10498:2:1;131707:59:0::1;::::0;::::1;10480:21:1::0;10537:1;10517:18;;;10510:29;10575:7;10555:18;;;10548:35;10600:18;;131707:59:0::1;10296:328:1::0;131707:59:0::1;131860:5;::::0;:9:::1;::::0;:5:::1;;::::0;:9:::1;:::i;:::-;131852:5;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;131897:41:0::1;131920:17:::0;131897:22:::1;:41::i;:::-;132098:5;::::0;79428:242;;;13921:16:1;79428:242:0;;;13905:102:1;14026:66;132052:11:0::1;14129:3:1::0;14125:16;;;14121:25;;14108:11;;;14101:46;14163:11;;;14156:27;;;14217:16;;;;;14199:12;;;14192:47;14273:16;;;14269:25;;14255:12;;;14248:47;14311:12;;;14304:28;;;14366:16;;;;14362:25;;;14348:12;;;14341:47;79428:242:0;;;;;;;;;14404:12:1;;;;79428:242:0;;131879:59;;-1:-1:-1;132266:21:0::1;132290:51;132312:7;132321:5;132328:12;132290:21;:51::i;:::-;132432:19:::0;;::::1;::::0;::::1;::::0;132266:75;;-1:-1:-1;132514:25:0::1;132432:19:::0;132514:11:::1;:25::i;:::-;132807:5;::::0;::::1;;136870:2:::0;136846:26;;;;;136845:37;132693:171:::1;;132751:1;132741:7;116793:10:::0;;;116729:81;132741:7:::1;:11;;;;:::i;:::-;132715:12;132693:171;132827:5;132846:8;132693:171;;;;;;;:::i;:::-;;;;;;;;131617:1254;;;;131398:1473:::0;;;;;:::o;47614:470::-;47714:16;;47769:19;:12;47714:16;47769;:19::i;:::-;47761:27;-1:-1:-1;33025:2:0;2732:26;16554:2;16550:16;;;16546:28;34279:37;47798:52;;;;-1:-1:-1;;;47798:52:0;;11446:2:1;47798:52:0;;;11428:21:1;11485:2;11465:18;;;11458:30;11524:20;11504:18;;;11497:48;11562:18;;47798:52:0;11244:342:1;47798:52:0;47871:115;47903:23;-1:-1:-1;;47903:21:0;;;:23::i;:::-;47940:36;:28;-1:-1:-1;;47940:26:0;;;:28::i;:::-;-1:-1:-1;;47940:34:0;;:36::i;:::-;47871:18;:115::i;:::-;47860:126;-1:-1:-1;48004:46:0;48014:25;-1:-1:-1;;48014:23:0;;;:25::i;:::-;48041:8;48004:9;:46::i;:::-;47996:81;;;;-1:-1:-1;;;47996:81:0;;11793:2:1;47996:81:0;;;11775:21:1;11832:2;11812:18;;;11805:30;11871:24;11851:18;;;11844:52;11913:18;;47996:81:0;11591:346:1;47996:81:0;47614:470;;;:::o;34677:136::-;34741:6;34773:32;-1:-1:-1;;34773:15:0;;32919:1;;34773:15;:32::i;34906:124::-;34969:7;34995:28;-1:-1:-1;;34995:11:0;;32966:1;35020:2;34995:11;:28::i;136064:283::-;136186:5;:21;;;;;;;;;;;;136242:48;;;;;136278:10;136242:14;:48;;2283:74:1;136242:14:0;;;;;;;;;;:27;;2256:18:1;;136242:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;136305:35:0;;136329:10;;-1:-1:-1;136305:35:0;;;;-1:-1:-1;136305:35:0;;;;;136064:283;:::o;55788:115::-;55851:7;55877:19;55885:3;51403:18;;51321:107;56245:156;56319:7;56369:22;56373:3;56385:5;56369:3;:22::i;:::-;56361:31;56245:156;-1:-1:-1;;;56245:156:0:o;135616:285::-;118516:19;;;;135696:81;;;;-1:-1:-1;;;135696:81:0;;12391:2:1;135696:81:0;;;12373:21:1;12430:2;12410:18;;;12403:30;12469:26;12449:18;;;12442:54;12513:18;;135696:81:0;12189:348:1;135696:81:0;135787:14;:49;;;;;;;;;;;;;;;;;;135851:43;;2283:74:1;;;135851:43:0;;2271:2:1;2256:18;135851:43:0;;;;;;;135616:285;:::o;56941:257::-;57004:16;57032:22;57057:19;57065:3;57057:7;:19::i;64146:207::-;64201:16;64243:21;:8;64256:7;64243:12;:21::i;:::-;64229:35;;64278:11;64274:73;;;64310:26;;2313:42:1;2301:55;;2283:74;;64310:26:0;;2271:2:1;2256:18;64310:26:0;;;;;;;64146:207;;;:::o;106858:808::-;107255:13;;106922:4;;107255:13;;;;;107251:409;;;107309:7;:12;;107320:1;107309:12;:61;;;;-1:-1:-1;107364:4:0;118516:19;:23;107309:61;107284:166;;;;-1:-1:-1;;;107284:166:0;;12744:2:1;107284:166:0;;;12726:21:1;12783:2;12763:18;;;12756:30;12822:34;12802:18;;;12795:62;12893:16;12873:18;;;12866:44;12927:19;;107284:166:0;12542:410:1;107284:166:0;-1:-1:-1;107471:5:0;;106858:808;-1:-1:-1;106858:808:0:o;107251:409::-;107515:12;;:22;;;;:12;;:22;107507:81;;;;-1:-1:-1;;;107507:81:0;;12744:2:1;107507:81:0;;;12726:21:1;12783:2;12763:18;;;12756:30;12822:34;12802:18;;;12795:62;12893:16;12873:18;;;12866:44;12927:19;;107507:81:0;12542:410:1;107507:81:0;-1:-1:-1;107602:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;106858:808:0:o;113609:108::-;106269:13;;;;;;;106261:69;;;;-1:-1:-1;;;106261:69:0;;13159:2:1;106261:69:0;;;13141:21:1;13198:2;13178:18;;;13171:30;13237:34;13217:18;;;13210:62;13308:13;13288:18;;;13281:41;13339:19;;106261:69:0;12957:407:1;106261:69:0;113684:26:::1;:24;:26::i;71146:122::-:0;71203:7;71229:32;71241:5;71248:12;:10;:12::i;:::-;71229:11;:32::i;110736:187::-;110828:6;;;;110844:17;;;;;;;;;;;110876:40;;110828:6;;;110844:17;110828:6;;110876:40;;110809:16;;110876:40;110799:124;110736:187;:::o;88128:122::-;88189:7;88215:28;:5;82150:10;88215:9;:28::i;89235:183::-;89308:6;89292:5;87135:35;82150:10;82143:18;-1:-1:-1;;87135:16:0;;;;:35::i;:::-;;89392:19:::1;89405:5;89392:12;:19::i;:::-;89373:16;89383:5;89373:9;:16::i;:::-;89353:17;89364:5;89353:10;:17::i;:::-;89333;89344:5;89333:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;89326:85;;87180:1;89235:183:::0;;;;:::o;137318:814::-;137424:14;90053:24;137458:48;;137454:672;;137558:10;137522:47;134662:780;-1:-1:-1;;134662:780:0:o;137454:672::-;137962:24;:22;:24::i;:::-;-1:-1:-1;90053:24:0;137318:814;;;:::o;83335:638::-;83631:14;;83480:12;;83588:17;;83086:29;83104:10;82957:1;83086:29;:::i;:::-;83608:13;;:38;;;;:::i;:::-;83588:58;;83656:17;83696:5;:12;83676:10;:33;;;;:::i;:::-;83656:53;-1:-1:-1;81807:1:0;83086:29;83104:10;82957:1;83086:29;:::i;:::-;83805:13;;83836:10;83864;83892:7;83917:5;83940:12;83738:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83719:247;;;;83335:638;;;;;:::o;116967:123::-;117022:18;:4;117034:5;117022:11;:18::i;:::-;117050:15;117071:11;:4;:9;:11::i;:::-;117050:33;;;;;;;-1:-1:-1;117050:33:0;;;;;;;;;;;-1:-1:-1;116967:123:0:o;13717:359::-;13821:10;;13787:7;;13968:4;13959:14;;14043:26;;;;13959:14;13821:10;14043:5;:26::i;:::-;14036:33;13717:359;-1:-1:-1;;;;;13717:359:0:o;35136:155::-;35199:7;35225:59;-1:-1:-1;;35225:11:0;;35199:7;33025:2;35199:7;35225:11;:59::i;35374:172::-;35442:7;35468:71;33025:2;35498:37;33025:2;16554;16550:16;;;2732:26;16546:28;35498:37;:::i;:::-;-1:-1:-1;;35468:11:0;;;:71;35537:1;35468:11;:71::i;28370:632::-;28425:16;28453:11;28474:12;28489;28493:7;16554:2;16550:16;2732:26;16546:28;;16308:282;28489:12;28474:27;;;;28611:4;28605:11;28598:18;;28666:3;28659:10;;28712:33;28725:7;28734:3;28740:4;28734:10;28712:12;:33::i;:::-;-1:-1:-1;28869:14:0;;;28885:4;28865:25;28859:4;28852:39;28932:17;;28370:632;;-1:-1:-1;28370:632:0:o;46778:285::-;46888:14;;46935;-1:-1:-1;;46935:12:0;;;:14::i;:::-;46918:31;;46968:36;46997:6;45371:58;;21671:66:1;45371:58:0;;;21659:79:1;21754:12;;;21747:28;;;45241:7:0;;21791:12:1;;45371:58:0;;;;;;;;;;;;45361:69;;;;;;45354:76;;45172:265;;;;46968:36;46959:45;;47023:33;47037:6;47045:10;47023:13;:33::i;:::-;47014:42;46778:285;-1:-1:-1;;;;46778:285:0:o;34420:143::-;34485:6;34517:38;-1:-1:-1;;34517:15:0;;34485:6;34553:1;34517:15;:38::i;64586:199::-;64670:4;64705:13;64694:24;;:7;:24;;;64686:49;;;;-1:-1:-1;;;64686:49:0;;16179:2:1;64686:49:0;;;16161:21:1;16218:2;16198:18;;;16191:30;16257:14;16237:18;;;16230:42;16289:18;;64686:49:0;15977:336:1;64686:49:0;64752:26;:8;64770:7;64752:17;:26::i;21183:221::-;21302:14;21380:11;21385:6;21380:2;:11;:::i;:::-;21379:17;;21395:1;21379:17;:::i;:::-;21335:62;;21343:30;21349:7;21358:6;21366;21343:5;:30::i;:::-;21335:62;;;21183:221;-1:-1:-1;;;;21183:221:0:o;20066:771::-;20181:14;20211:6;:11;;20221:1;20211:11;20207:59;;-1:-1:-1;20253:1:0;20238:17;;20207:59;20297:12;20301:7;16554:2;16550:16;2732:26;16546:28;;16308:282;20297:12;20279:30;;:15;;;;:6;:15;:::i;:::-;:30;20275:137;;;20332:68;20348:12;20352:7;15448:3;15444:17;2732:26;15440:29;;15121:364;20348:12;20332:68;;20362:12;20366:7;16554:2;16550:16;2732:26;16546:28;;16308:282;20362:12;20332:68;;20376:6;20392;20384:15;;20332;:68::i;:::-;20325:76;;-1:-1:-1;;;20325:76:0;;;;;;;;:::i;20275:137::-;20439:2;20429:6;:12;;;;20421:83;;;;-1:-1:-1;;;20421:83:0;;17077:2:1;20421:83:0;;;17059:21:1;17116:2;17096:18;;;17089:30;17155:34;17135:18;;;17128:62;17226:28;17206:18;;;17199:56;17272:19;;20421:83:0;16875:422:1;20421:83:0;20585:1;20576:10;;20515:15;20621:12;20625:7;15448:3;15444:17;2732:26;15440:29;;15121:364;20621:12;20606:27;;;-1:-1:-1;20643:13:0;7550:66;7520:12;;;7499:131;20795:17;;;;20789:24;20785:36;;;-1:-1:-1;;;;;20066:771:0:o;51770:118::-;51837:7;51863:3;:11;;51875:5;51863:18;;;;;;;;:::i;:::-;;;;;;;;;51856:25;;51770:118;;;;:::o;52428:109::-;52484:16;52519:3;:11;;52512:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52428:109;;;:::o;54987:150::-;55057:4;55080:50;55085:3;55105:23;;;55080:4;:50::i;109315:111::-;106269:13;;;;;;;106261:69;;;;-1:-1:-1;;;106261:69:0;;13159:2:1;106261:69:0;;;13141:21:1;13198:2;13178:18;;;13171:30;13237:34;13217:18;;;13210:62;13308:13;13288:18;;;13281:41;13339:19;;106261:69:0;12957:407:1;106261:69:0;109387:32:::1;108502:10:::0;109387:18:::1;:32::i;71386:964::-:0;71431:34;;:::i;:::-;71490:3;71477:16;;71516:3;71477:10;71503;;:16;71542:3;71529:10;;;:16;71568:3;71555:10;;;:16;71594:3;71581:10;;;:16;71620:3;71607:10;;;:16;71646:3;71633:10;;;:16;71672:3;71659:10;;;:16;71698:3;71685:10;;;:16;71724:3;71711:10;;;:16;71751:4;71737:11;;;:18;71779:4;71765:11;;;:18;71807:4;71793:11;;;:18;71835:4;71821:11;;;:18;71863:4;71849:11;;;:18;71891:4;71877:11;;;:18;71919:4;71905:11;;;:18;71947:4;71933:11;;;:18;71975:4;71961:11;;;:18;72003:4;71989:11;;;:18;72031:4;72017:11;;;:18;72059:4;72045:11;;;:18;72087:4;72073:11;;;:18;72115:4;72101:11;;;:18;72143:4;72129:11;;;:18;72171:4;72157:11;;;:18;72199:4;72185:11;;;:18;72227:4;72213:11;;;:18;72255:4;72241:11;;;:18;72283:4;72269:11;;;:18;72311:4;72297:11;;;:18;72339:4;72325:11;;;:18;71477:7;71386:964::o;70490:589::-;70663:11;;;;70614:16;;;70685:388;69070:2;70705:1;:14;70685:388;;;70771:4;70756:11;;;70755:20;;;70793:12;;;70789:215;;70863:5;70876:1;70863:15;;;;;;;:::i;:::-;;;70846:43;;;;;;17459:19:1;;;;17494:12;;17487:28;;;17531:12;;70846:43:0;;;;;;;;;;;;70836:54;;;;;;70825:65;;70789:215;;;70967:8;70977:7;70985:1;70977:10;;;;;;;:::i;:::-;;;;;70950:38;;;;;;;;17459:19:1;;;17503:2;17494:12;;17487:28;17540:2;17531:12;;17302:247;70950:38:0;;;;;;;;;;;;;70940:49;;;;;;70929:60;;70789:215;-1:-1:-1;71045:3:0;;70685:388;;;;70636:443;70490:589;;;;:::o;10135:578::-;10213:7;10237:26;10244:7;10253:9;10237:6;:26::i;:::-;10232:451;;10282:9;10295:35;10313:15;10320:7;14479:3;14475:17;;14268:268;10313:15;10305:24;;10295:9;:35::i;:::-;10279:51;;;10347:9;10360:29;10378:9;10370:18;;10360:9;:29::i;:::-;10447:186;;17921:31:1;10447:186:0;;;17909:44:1;17972:66;18076:3;18072:16;;;18068:25;;18054:12;;;18047:47;18124:15;18110:12;;;18103:37;18174:16;;;18170:25;18156:12;;;18149:47;10344:45:0;;-1:-1:-1;10403:17:0;;-1:-1:-1;18212:12:1;;10447:186:0;;;;;;;;;;;;10403:244;;10668:3;10661:11;;-1:-1:-1;;;10661:11:0;;;;;;;;:::i;10232:451::-;-1:-1:-1;10699:7:0;;10135:578;-1:-1:-1;10135:578:0:o;89076:153::-;89152:6;89136:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;89184:37:0::1;-1:-1:-1::0;;89184:15:0;::::1;87083:2;89218;89184:15;:37::i;:::-;89170:52;;::::0;89076:153;-1:-1:-1;;;89076:153:0:o;88880:147::-;88953:6;88937:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88985:34:0::1;-1:-1:-1::0;;88985:15:0;::::1;87030:2;89016;88985:15;:34::i;88685:149::-:0;88759:6;88743:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88791:35:0::1;-1:-1:-1::0;;88791:15:0;::::1;86980:2;88823;88791:15;:35::i;88489:149::-:0;88563:6;88547:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88595:35:0::1;-1:-1:-1::0;;88595:15:0;::::1;86930:1;88627:2;88595:15;:35::i;115988:132::-:0;116076:15;;;;116054:10;:38;116046:67;;;;-1:-1:-1;;;116046:67:0;;18437:2:1;116046:67:0;;;18419:21:1;18476:2;18456:18;;;18449:30;18515:18;18495;;;18488:46;18551:18;;116046:67:0;18235:340:1;69529:750:0;69614:11;;;;;;69133:1;;69117:13;;:1;:13;:::i;:::-;:17;;;;:::i;:::-;69643:4;:17;69635:46;;;;-1:-1:-1;;;69635:46:0;;20276:2:1;69635:46:0;;;20258:21:1;20315:2;20295:18;;;20288:30;20354:18;20334;;;20327:46;20390:18;;69635:46:0;20074:340:1;69635:46:0;69716:6;;69742:11;;;:18;;;69775:9;69770:319;69070:2;69790:1;:14;69770:319;;;69827:4;69834:1;69827:8;69840:1;69826:15;69822:101;;69879:5;69861;69874:1;69861:15;;;;;;;:::i;:::-;;:23;-1:-1:-1;;;;69529:750:0:o;69822:101::-;69971:5;69984:1;69971:15;;;;;;;:::i;:::-;;;69954:40;;;;;;17459:19:1;;;;17494:12;;17487:28;;;17531:12;;69954:40:0;;;;;;;;;;;;;69944:51;;69954:40;69944:51;;;;;-1:-1:-1;70018:1:0;70009:10;;;;70061:3;69770:319;;;-1:-1:-1;70259:13:0;;:::i;:::-;69589:690;69529:750;;:::o;12858:462::-;12969:15;;13011:11;13018:4;13011;:11;:::i;:::-;12996:26;;13137:4;13131:11;13125:4;13122:21;13119:66;;;-1:-1:-1;13170:1:0;13119:66;13208:4;13216:1;13208:9;13204:51;;-1:-1:-1;;13233:11:0;;;;;13204:51;-1:-1:-1;;12127:2:0;12123:27;;;12197:17;;;;12189:26;;;12261:17;12257:2;12253:26;;12858:462::o;17191:399::-;17330:7;17349:12;17364;17368:7;15448:3;15444:17;2732:26;15440:29;;15121:364;17364:12;17349:27;;;;17460:12;17464:7;17460:3;:12::i;:::-;17453:4;17437:13;17444:6;17437:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17433:77;;;-1:-1:-1;;17488:11:0;;;;;17433:77;17527:13;17534:6;17527:4;:13;:::i;:::-;17520:20;;17557:26;17563:7;17557:26;;17572:4;17578;17557:5;:26::i;:::-;17550:33;17191:399;-1:-1:-1;;;;;;17191:399:0:o;27098:902::-;27176:15;-1:-1:-1;;8034:15:0;;;;27203:69;;;;-1:-1:-1;;;27203:69:0;;20810:2:1;27203:69:0;;;20792:21:1;20849:2;20829:18;;;20822:30;20888:34;20868:18;;;20861:62;20959:10;20939:18;;;20932:38;20987:19;;27203:69:0;20608:404:1;27203:69:0;27290:16;27298:7;27290;:16::i;:::-;27282:72;;;;-1:-1:-1;;;27282:72:0;;21219:2:1;27282:72:0;;;21201:21:1;21258:2;21238:18;;;21231:30;21297:34;21277:18;;;21270:62;21368:13;21348:18;;;21341:41;21399:19;;27282:72:0;21017:407:1;27282:72:0;27364:12;27379;27383:7;16554:2;16550:16;2732:26;16546:28;;16308:282;27379:12;27364:27;;;;27401:15;27419:12;27423:7;15448:3;15444:17;2732:26;15440:29;;15121:364;27419:12;27401:30;;;;27442:11;27563:4;27557:11;27550:18;;27650:7;27645:3;27642:16;27639:94;;;27690:4;27684;27677:18;27639:94;27905:4;27896:7;27890:4;27881:7;27878:1;27871:5;27860:50;27856:55;27941:52;27962:15;27969:7;14479:3;14475:17;;14268:268;27962:15;12123:27;12127:2;12123:27;;;;12197:17;;12189:26;;12261:17;;12257:2;12253:26;;11873:446;22517:290;22573:14;22599:12;22614;22618:7;15448:3;15444:17;2732:26;15440:29;;15121:364;22614:12;22599:27;;;;22636:12;22651;22655:7;16554:2;16550:16;2732:26;16546:28;;16308:282;22651:12;22636:27;;22770:21;;;;22517:290;-1:-1:-1;;;22517:290:0:o;41468:227::-;41546:7;41566:17;41585:18;41607:27;41618:4;41624:9;41607:10;:27::i;:::-;41565:69;;;;41644:18;41656:5;41644:11;:18::i;:::-;-1:-1:-1;41679:9:0;41468:227;-1:-1:-1;;;41468:227:0:o;55542:165::-;55675:23;;;55622:4;51209:19;;;:12;;;:19;;;;;;:24;;55645:55;51113:127;18823:741;18969:17;19001:9;19014:15;19024:4;19014:9;:15::i;:::-;18998:31;;;19042:9;19055:15;19065:4;19055:9;:15::i;:::-;19039:31;;;19083:9;19096:17;19106:6;19096:9;:17::i;:::-;19080:33;;;19126:9;19139:17;19149:6;19139:9;:17::i;:::-;19123:33;;;19306:1;19368;19448;19510;19192:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19166:391;;18988:576;;;;18823:741;;;;;;:::o;49072:404::-;49135:4;51209:19;;;:12;;;:19;;;;;;49151:319;;-1:-1:-1;49193:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;49373:18;;49351:19;;;:12;;;:19;;;;;;:40;;;;49405:11;;49151:319;-1:-1:-1;49454:5:0;49447:12;;9705:132;9779:4;9821:9;9802:28;;:15;9809:7;14479:3;14475:17;;14268:268;9802:15;:28;;;;9705:132;-1:-1:-1;;;9705:132:0:o;5093:667::-;5147:13;;5203:2;5188:258;5211:2;5207:1;:6;;;5188:258;;;5231:11;5258:5;:1;5262;5258:5;:::i;:::-;5251:13;;:2;:13;;5231:34;;5288:14;5296:5;5288:7;:14::i;:::-;5279:23;;;;;;5320:1;:7;;5325:2;5320:7;5316:58;;5357:2;5347:12;;;;;5316:58;-1:-1:-1;5415:6:0;;5188:258;;;-1:-1:-1;5509:2:0;5494:260;5517:3;5513:1;:7;;;5494:260;;;5538:11;5565:5;:1;5569;5565:5;:::i;:::-;5558:13;;:2;:13;;5538:34;;5596:14;5604:5;5596:7;:14::i;:::-;5586:24;;;;;;5628:1;:6;;5633:1;5628:6;5624:58;;5665:2;5654:13;;;;;5624:58;-1:-1:-1;5723:6:0;;5494:260;;;;5093:667;;;:::o;16764:147::-;16817:7;16882:12;16886:7;16554:2;16550:16;2732:26;16546:28;;16308:282;16882:12;16867;16871:7;15448:3;15444:17;2732:26;15440:29;;15121:364;16867:12;:27;16860:34;;;;16764:147;;;:::o;8707:333::-;8764:8;8788:15;8795:7;14479:3;14475:17;;14268:268;8788:15;:31;;8807:12;8788:31;8784:74;;-1:-1:-1;8842:5:0;;8707:333;-1:-1:-1;8707:333:0:o;8784:74::-;8867:12;8882;8886:7;8882:3;:12::i;:::-;9017:4;9011:11;-1:-1:-1;8998:26:0;;8707:333;-1:-1:-1;;;8707:333:0:o;39403:1279::-;39484:7;39493:12;39714:9;:16;39734:2;39714:22;39710:966;;40003:4;39988:20;;39982:27;40052:4;40037:20;;40031:27;40109:4;40094:20;;40088:27;39752:9;40080:36;40150:25;40161:4;40080:36;39982:27;40031;40150:10;:25::i;:::-;40143:32;;;;;;;;;39710:966;40196:9;:16;40216:2;40196:22;40192:484;;40465:4;40450:20;;40444:27;40515:4;40500:20;;40494:27;40555:23;40566:4;40444:27;40494;40555:10;:23::i;:::-;40548:30;;;;;;;;40192:484;-1:-1:-1;40625:1:0;;-1:-1:-1;40629:35:0;40192:484;39403:1279;;;;;:::o;37708:631::-;37785:20;37776:5;:29;;;;;;;;:::i;:::-;;37772:561;;37708:631;:::o;37772:561::-;37881:29;37872:5;:38;;;;;;;;:::i;:::-;;37868:465;;37926:34;;-1:-1:-1;;;37926:34:0;;23531:2:1;37926:34:0;;;23513:21:1;23570:2;23550:18;;;23543:30;23609:26;23589:18;;;23582:54;23653:18;;37926:34:0;23329:348:1;37868:465:0;37990:35;37981:5;:44;;;;;;;;:::i;:::-;;37977:356;;38041:41;;-1:-1:-1;;;38041:41:0;;23884:2:1;38041:41:0;;;23866:21:1;23923:2;23903:18;;;23896:30;23962:33;23942:18;;;23935:61;24013:18;;38041:41:0;23682:355:1;37977:356:0;38112:30;38103:5;:39;;;;;;;;:::i;:::-;;38099:234;;38158:44;;-1:-1:-1;;;38158:44:0;;24244:2:1;38158:44:0;;;24226:21:1;24283:2;24263:18;;;24256:30;24322:34;24302:18;;;24295:62;24393:4;24373:18;;;24366:32;24415:19;;38158:44:0;24042:398:1;38099:234:0;38232:30;38223:5;:39;;;;;;;;:::i;:::-;;38219:114;;38278:44;;-1:-1:-1;;;38278:44:0;;24647:2:1;38278:44:0;;;24629:21:1;24686:2;24666:18;;;24659:30;24725:34;24705:18;;;24698:62;24796:4;24776:18;;;24769:32;24818:19;;38278:44:0;24445:398:1;4570:199:0;4620:14;4657:18;4673:1;4667:2;:7;;;;4657:9;:18::i;:::-;4646:29;;4699:13;;;;;;4711:1;4699:13;4733;4743:2;4733:9;:13::i;:::-;4722:24;;;;4570:199;-1:-1:-1;4570:199:0:o;42876:1603::-;43002:7;;43926:66;43913:79;;43909:161;;;-1:-1:-1;44024:1:0;;-1:-1:-1;44028:30:0;44008:51;;43909:161;44083:1;:7;;44088:2;44083:7;;:18;;;;;44094:1;:7;;44099:2;44094:7;;44083:18;44079:100;;;-1:-1:-1;44133:1:0;;-1:-1:-1;44137:30:0;44117:51;;44079:100;44290:24;;;44273:14;44290:24;;;;;;;;;25075:25:1;;;25148:4;25136:17;;25116:18;;;25109:45;;;;25170:18;;;25163:34;;;25213:18;;;25206:34;;;44290:24:0;;25047:19:1;;44290:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44290:24:0;;;;;;-1:-1:-1;;44328:20:0;;;44324:101;;44380:1;44384:29;44364:50;;;;;;;44324:101;44443:6;-1:-1:-1;44451:20:0;;-1:-1:-1;42876:1603:0;;;;;;;;:::o;41949:336::-;42059:7;;42117:66;42104:80;;42059:7;42210:25;42226:3;42211:18;;;42233:2;42210:25;:::i;:::-;42194:42;;42253:25;42264:4;42270:1;42273;42276;42253:10;:25::i;:::-;42246:32;;;;;;41949:336;;;;;;:::o;3005:1393::-;3057:10;3223:4;3218:9;;;;3269:15;;;;;3265:57;;-1:-1:-1;3307:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3265:57::-;3340:7;:15;;3351:4;3340:15;3336:57;;-1:-1:-1;3378:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3336:57::-;3411:7;:15;;3422:4;3411:15;3407:57;;-1:-1:-1;3449:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3407:57::-;3482:7;:15;;3493:4;3482:15;3478:57;;-1:-1:-1;3520:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3478:57::-;3553:7;:15;;3564:4;3553:15;3549:57;;-1:-1:-1;3591:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3549:57::-;3624:7;:15;;3635:4;3624:15;3620:57;;-1:-1:-1;3662:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3620:57::-;3695:7;:15;;3706:4;3695:15;3691:57;;-1:-1:-1;3733:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3691:57::-;3766:7;:15;;3777:4;3766:15;3762:57;;-1:-1:-1;3804:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3762:57::-;3837:7;:15;;3848:4;3837:15;3833:57;;-1:-1:-1;3875:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3833:57::-;3908:7;:15;;3919:4;3908:15;3904:57;;-1:-1:-1;3946:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3904:57::-;3979:7;:15;;3990:4;3979:15;3975:57;;-1:-1:-1;4017:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3975:57::-;4050:7;:15;;4061:4;4050:15;4046:57;;-1:-1:-1;4088:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4046:57::-;4121:7;:15;;4132:4;4121:15;4117:57;;-1:-1:-1;4159:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4117:57::-;4192:7;:15;;4203:4;4192:15;4188:57;;-1:-1:-1;4230:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4188:57::-;4263:7;:15;;4274:4;4263:15;4259:57;;-1:-1:-1;4301:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4259:57::-;4334:7;:15;;4345:4;4334:15;4330:57;;-1:-1:-1;4372:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:184:1:-;248:77;245:1;238:88;345:4;342:1;335:15;369:4;366:1;359:15;385:777;427:5;480:3;473:4;465:6;461:17;457:27;447:55;;498:1;495;488:12;447:55;534:6;521:20;560:18;597:2;593;590:10;587:36;;;603:18;;:::i;:::-;737:2;731:9;799:4;791:13;;642:66;787:22;;;811:2;783:31;779:40;767:53;;;835:18;;;855:22;;;832:46;829:72;;;881:18;;:::i;:::-;921:10;917:2;910:22;956:2;948:6;941:18;1002:3;995:4;990:2;982:6;978:15;974:26;971:35;968:55;;;1019:1;1016;1009:12;968:55;1083:2;1076:4;1068:6;1064:17;1057:4;1049:6;1045:17;1032:54;1130:1;1123:4;1118:2;1110:6;1106:15;1102:26;1095:37;1150:6;1141:15;;;;;;385:777;;;;:::o;1167:320::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;1344:9;1331:23;1377:18;1369:6;1366:30;1363:50;;;1409:1;1406;1399:12;1363:50;1432:49;1473:7;1464:6;1453:9;1449:22;1432:49;:::i;1952:180::-;2011:6;2064:2;2052:9;2043:7;2039:23;2035:32;2032:52;;;2080:1;2077;2070:12;2032:52;-1:-1:-1;2103:23:1;;1952:180;-1:-1:-1;1952:180:1:o;2747:154::-;2833:42;2826:5;2822:54;2815:5;2812:65;2802:93;;2891:1;2888;2881:12;2906:247;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3073:9;3060:23;3092:31;3117:5;3092:31;:::i;3158:681::-;3329:2;3381:21;;;3451:13;;3354:18;;;3473:22;;;3300:4;;3329:2;3552:15;;;;3526:2;3511:18;;;3300:4;3595:218;3609:6;3606:1;3603:13;3595:218;;;3674:13;;3689:42;3670:62;3658:75;;3788:15;;;;3753:12;;;;3631:1;3624:9;3595:218;;;-1:-1:-1;3830:3:1;;3158:681;-1:-1:-1;;;;;;3158:681:1:o;4376:184::-;4428:77;4425:1;4418:88;4525:4;4522:1;4515:15;4549:4;4546:1;4539:15;4565:396;4708:2;4693:18;;4741:1;4730:13;;4720:201;;4777:77;4774:1;4767:88;4878:4;4875:1;4868:15;4906:4;4903:1;4896:15;4720:201;4930:25;;;4565:396;:::o;5498:163::-;5565:20;;5625:10;5614:22;;5604:33;;5594:61;;5651:1;5648;5641:12;5666:753;5777:6;5785;5793;5801;5809;5862:3;5850:9;5841:7;5837:23;5833:33;5830:53;;;5879:1;5876;5869:12;5830:53;5902:28;5920:9;5902:28;:::i;:::-;5892:38;;5977:2;5966:9;5962:18;5949:32;5939:42;;6000:37;6033:2;6022:9;6018:18;6000:37;:::i;:::-;5990:47;;6088:2;6077:9;6073:18;6060:32;6111:18;6152:2;6144:6;6141:14;6138:34;;;6168:1;6165;6158:12;6138:34;6191:49;6232:7;6223:6;6212:9;6208:22;6191:49;:::i;:::-;6181:59;;6293:3;6282:9;6278:19;6265:33;6249:49;;6323:2;6313:8;6310:16;6307:36;;;6339:1;6336;6329:12;6307:36;;6362:51;6405:7;6394:8;6383:9;6379:24;6362:51;:::i;:::-;6352:61;;;5666:753;;;;;;;;:::o;6954:184::-;7006:77;7003:1;6996:88;7103:4;7100:1;7093:15;7127:4;7124:1;7117:15;7143:258;7215:1;7225:113;7239:6;7236:1;7233:13;7225:113;;;7315:11;;;7309:18;7296:11;;;7289:39;7261:2;7254:10;7225:113;;;7356:6;7353:1;7350:13;7347:48;;;7391:1;7382:6;7377:3;7373:16;7366:27;7347:48;;7143:258;;;:::o;7406:316::-;7447:3;7485:5;7479:12;7512:6;7507:3;7500:19;7528:63;7584:6;7577:4;7572:3;7568:14;7561:4;7554:5;7550:16;7528:63;:::i;:::-;7636:2;7624:15;7641:66;7620:88;7611:98;;;;7711:4;7607:109;;7406:316;-1:-1:-1;;7406:316:1:o;7727:337::-;7914:42;7906:6;7902:55;7891:9;7884:74;7994:2;7989;7978:9;7974:18;7967:30;7865:4;8014:44;8054:2;8043:9;8039:18;8031:6;8014:44;:::i;8069:184::-;8121:77;8118:1;8111:88;8218:4;8215:1;8208:15;8242:4;8239:1;8232:15;8258:125;8298:4;8326:1;8323;8320:8;8317:34;;;8331:18;;:::i;:::-;-1:-1:-1;8368:9:1;;8258:125::o;9093:251::-;9163:6;9216:2;9204:9;9195:7;9191:23;9187:32;9184:52;;;9232:1;9229;9222:12;9184:52;9264:9;9258:16;9283:31;9308:5;9283:31;:::i;10629:228::-;10668:3;10696:10;10733:2;10730:1;10726:10;10763:2;10760:1;10756:10;10794:3;10790:2;10786:12;10781:3;10778:21;10775:47;;;10802:18;;:::i;:::-;10838:13;;10629:228;-1:-1:-1;;;;10629:228:1:o;10862:377::-;11055:2;11044:9;11037:21;11018:4;11081:44;11121:2;11110:9;11106:18;11098:6;11081:44;:::i;:::-;11173:9;11165:6;11161:22;11156:2;11145:9;11141:18;11134:50;11201:32;11226:6;11218;11201:32;:::i;13369:244::-;13408:3;13436:26;13489:2;13486:1;13482:10;13519:2;13516:1;13512:10;13550:3;13546:2;13542:12;13537:3;13534:21;13531:47;;;13558:18;;:::i;14427:238::-;14465:7;14505:4;14502:1;14498:12;14537:4;14534:1;14530:12;14597:3;14591:4;14587:14;14582:3;14579:23;14572:3;14565:11;14558:19;14554:49;14551:75;;;14606:18;;:::i;:::-;14646:13;;14427:238;-1:-1:-1;;;14427:238:1:o;14670:224::-;14709:3;14737:6;14770:2;14767:1;14763:10;14800:2;14797:1;14793:10;14831:3;14827:2;14823:12;14818:3;14815:21;14812:47;;;14839:18;;:::i;14899:1073::-;15224:3;15252:66;15361:2;15352:6;15347:3;15343:16;15339:25;15334:3;15327:38;15416:2;15407:6;15402:3;15398:16;15394:25;15390:1;15385:3;15381:11;15374:46;15471:2;15462:6;15457:3;15453:16;15449:25;15445:1;15440:3;15436:11;15429:46;15526:2;15517:6;15512:3;15508:16;15504:25;15500:1;15495:3;15491:11;15484:46;;15559:6;15553:13;15575:61;15629:6;15625:1;15620:3;15616:11;15609:4;15601:6;15597:17;15575:61;:::i;:::-;15696:13;;15655:16;;;;15718:62;15696:13;15767:1;15759:10;;15752:4;15740:17;;15718:62;:::i;:::-;15841:13;;15799:17;;;15863:62;15841:13;15912:1;15904:10;;15897:4;15885:17;;15863:62;:::i;:::-;15945:17;15964:1;15941:25;;14899:1073;-1:-1:-1;;;;;;;;;14899:1073:1:o;16318:195::-;16356:4;16393;16390:1;16386:12;16425:4;16422:1;16418:12;16450:3;16445;16442:12;16439:38;;;16457:18;;:::i;:::-;16494:13;;;16318:195;-1:-1:-1;;;16318:195:1:o;16518:128::-;16558:3;16589:1;16585:6;16582:1;16579:13;16576:39;;;16595:18;;:::i;:::-;-1:-1:-1;16631:9:1;;16518:128::o;16651:219::-;16800:2;16789:9;16782:21;16763:4;16820:44;16860:2;16849:9;16845:18;16837:6;16820:44;:::i;18580:482::-;18669:1;18712:5;18669:1;18726:330;18747:7;18737:8;18734:21;18726:330;;;18866:4;18798:66;18794:77;18788:4;18785:87;18782:113;;;18875:18;;:::i;:::-;18925:7;18915:8;18911:22;18908:55;;;18945:16;;;;18908:55;19024:22;;;;18984:15;;;;18726:330;;;18730:3;18580:482;;;;;:::o;19067:866::-;19116:5;19146:8;19136:80;;-1:-1:-1;19187:1:1;19201:5;;19136:80;19235:4;19225:76;;-1:-1:-1;19272:1:1;19286:5;;19225:76;19317:4;19335:1;19330:59;;;;19403:1;19398:130;;;;19310:218;;19330:59;19360:1;19351:10;;19374:5;;;19398:130;19435:3;19425:8;19422:17;19419:43;;;19442:18;;:::i;:::-;-1:-1:-1;;19498:1:1;19484:16;;19513:5;;19310:218;;19612:2;19602:8;19599:16;19593:3;19587:4;19584:13;19580:36;19574:2;19564:8;19561:16;19556:2;19550:4;19547:12;19543:35;19540:77;19537:159;;;-1:-1:-1;19649:19:1;;;19681:5;;19537:159;19728:34;19753:8;19747:4;19728:34;:::i;:::-;19858:6;19790:66;19786:79;19777:7;19774:92;19771:118;;;19869:18;;:::i;19938:131::-;19998:5;20027:36;20054:8;20048:4;20027:36;:::i;20419:184::-;20471:77;20468:1;20461:88;20568:4;20565:1;20558:15;20592:4;20589:1;20582:15;21933:1391;22655:34;22643:47;;22720:23;22715:2;22706:12;;22699:45;22763:66;22867:3;22863:16;;;22859:25;;22854:2;22845:12;;22838:47;22904:17;22946:2;22937:12;;22930:24;;;22988:16;;;22984:25;;22979:2;22970:12;;22963:47;23040:34;23035:2;23026:12;;23019:56;23106:3;23100;23091:13;;23084:26;23145:16;;;23141:25;;23135:3;23126:13;;23119:48;23192:3;23183:13;;23176:25;23236:16;;;23232:25;23226:3;23217:13;;23210:48;21891:3;23313;23304:13;;21879:16;-1:-1:-1;21911:11:1;;;23274:44;21814:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"leafIndex","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"destinationAndNonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"tips","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Dispatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"ImproperAttestation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updaterManager","type":"address"}],"name":"NewUpdaterManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"address","name":"reporter","type":"address"}],"name":"UpdaterSlashed","type":"event"},{"inputs":[],"name":"MAX_MESSAGE_BODY_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allNotaries","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipientAddress","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNotary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"improperAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUpdaterManager","name":"_updaterManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notariesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterManager","type":"address"}],"name":"setUpdaterManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Home.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"suggestUpdate","outputs":[{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updaterManager","outputs":[{"internalType":"contract IUpdaterManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"notice":"Emitted when a new message is dispatched via Nomad"},"ImproperAttestation(address,bytes)":{"notice":"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state"},"NewUpdaterManager(address)":{"notice":"Emitted when the UpdaterManager contract is changed"},"UpdaterSlashed(address,address)":{"notice":"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)"}},"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"notice":"Dispatch the message to the destination domain \u0026 recipient"},"improperAttestation(bytes)":{"notice":"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation."},"root()":{"notice":"Calculates and returns tree's current root"},"setUpdater(address)":{"notice":"Set a new Updater"},"setUpdaterManager(address)":{"notice":"Set a new UpdaterManager contract"},"suggestUpdate()":{"notice":"Suggest an update for the Updater to sign and submit."}},"notice":"Accepts messages to be dispatched to remote chains, constructs a Merkle tree of the messages, and accepts signatures from a bonded Updater which notarize the Merkle tree roots. Accepts submissions of fraudulent signatures by the Updater and slashes the Updater in this case.","version":1},"developerDoc":{"author":"Illusory Systems Inc.","events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"params":{"destinationAndNonce":"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)","leafIndex":"Index of message's leaf in merkle tree","message":"Raw bytes of message","messageHash":"Hash of message; the leaf inserted to the Merkle tree for the message","tips":"Tips paid for the remote off-chain agents"}},"ImproperAttestation(address,bytes)":{"params":{"attestation":"Attestation data and signature","updater":"Updater who signed improper attestation"}},"NewUpdaterManager(address)":{"params":{"updaterManager":"The address of the new updaterManager"}},"UpdaterSlashed(address,address)":{"params":{"reporter":"The address of the entity that reported the updater misbehavior","updater":"The address of the updater"}}},"kind":"dev","methods":{"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"details":"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.","params":{"_destinationDomain":"Domain of destination chain","_messageBody":"Raw bytes content of message","_recipientAddress":"Address of recipient on destination chain as bytes32"}},"improperAttestation(bytes)":{"details":"Reverts (and doesn't slash updater) if signature is invalid or update not current","params":{"_attestation":"Attestation data and signature"},"returns":{"_0":"TRUE if update was an Improper Attestation (implying Updater was slashed)"}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setUpdater(address)":{"details":"To be set when rotating Updater after Fraud","params":{"_updater":"the new Updater"}},"setUpdaterManager(address)":{"details":"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation","params":{"_updaterManager":"the new UpdaterManager contract"}},"suggestUpdate()":{"details":"If no messages have been sent, null bytes returned for both","returns":{"_nonce":"Current nonce","_root":"Current merkle root"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"title":"Home","version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum Home.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Illusory Systems Inc.\",\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"params\":{\"destinationAndNonce\":\"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\",\"leafIndex\":\"Index of message's leaf in merkle tree\",\"message\":\"Raw bytes of message\",\"messageHash\":\"Hash of message; the leaf inserted to the Merkle tree for the message\",\"tips\":\"Tips paid for the remote off-chain agents\"}},\"ImproperAttestation(address,bytes)\":{\"params\":{\"attestation\":\"Attestation data and signature\",\"updater\":\"Updater who signed improper attestation\"}},\"NewUpdaterManager(address)\":{\"params\":{\"updaterManager\":\"The address of the new updaterManager\"}},\"UpdaterSlashed(address,address)\":{\"params\":{\"reporter\":\"The address of the entity that reported the updater misbehavior\",\"updater\":\"The address of the updater\"}}},\"kind\":\"dev\",\"methods\":{\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"details\":\"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.\",\"params\":{\"_destinationDomain\":\"Domain of destination chain\",\"_messageBody\":\"Raw bytes content of message\",\"_recipientAddress\":\"Address of recipient on destination chain as bytes32\"}},\"improperAttestation(bytes)\":{\"details\":\"Reverts (and doesn't slash updater) if signature is invalid or update not current\",\"params\":{\"_attestation\":\"Attestation data and signature\"},\"returns\":{\"_0\":\"TRUE if update was an Improper Attestation (implying Updater was slashed)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setUpdater(address)\":{\"details\":\"To be set when rotating Updater after Fraud\",\"params\":{\"_updater\":\"the new Updater\"}},\"setUpdaterManager(address)\":{\"details\":\"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\",\"params\":{\"_updaterManager\":\"the new UpdaterManager contract\"}},\"suggestUpdate()\":{\"details\":\"If no messages have been sent, null bytes returned for both\",\"returns\":{\"_nonce\":\"Current nonce\",\"_root\":\"Current merkle root\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"Home\",\"version\":1},\"userdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"notice\":\"Emitted when a new message is dispatched via Nomad\"},\"ImproperAttestation(address,bytes)\":{\"notice\":\"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state\"},\"NewUpdaterManager(address)\":{\"notice\":\"Emitted when the UpdaterManager contract is changed\"},\"UpdaterSlashed(address,address)\":{\"notice\":\"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)\"}},\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Dispatch the message to the destination domain \u0026 recipient\"},\"improperAttestation(bytes)\":{\"notice\":\"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation.\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"},\"setUpdater(address)\":{\"notice\":\"Set a new Updater\"},\"setUpdaterManager(address)\":{\"notice\":\"Set a new UpdaterManager contract\"},\"suggestUpdate()\":{\"notice\":\"Suggest an update for the Updater to sign and submit.\"}},\"notice\":\"Accepts messages to be dispatched to remote chains, constructs a Merkle tree of the messages, and accepts signatures from a bonded Updater which notarize the Merkle tree roots. Accepts submissions of fraudulent signatures by the Updater and slashes the Updater in this case.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Home\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"MAX_MESSAGE_BODY_BYTES()":"522ae002","VERSION()":"ffa1ad74","allGuards()":"9fe03fa2","allNotaries()":"9817e315","count()":"06661abd","dispatch(uint32,bytes32,uint32,bytes,bytes)":"f7560e40","getGuard(uint256)":"629ddf69","getNotary(uint256)":"c07dc7f5","guardsAmount()":"246c2449","historicalRoots(uint256)":"7ea97f40","improperAttestation(bytes)":"0afe7f90","initialize(address)":"c4d66de8","localDomain()":"8d3638f4","nonce()":"affed0e0","notariesAmount()":"8e62e9ef","owner()":"8da5cb5b","renounceOwnership()":"715018a6","root()":"ebf0c717","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","setUpdaterManager(address)":"9776120e","state()":"c19d93fb","suggestUpdate()":"36e104de","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","tree()":"fd54b228","updaterManager()":"9df6c8e1"}},"solidity/Home.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/Home.sol:IUpdaterManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"address payable","name":"_reporter","type":"address"}],"name":"slashUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"IUpdaterManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"slashUpdater(address)":"5b3c2cbf","updater()":"df034cd0"}},"solidity/Home.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"custom:oz-upgrades-unsafe-allow":"constructor constructor() { _disableInitializers(); } ``` ====","details":"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\"MyToken\", \"MTK\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\"MyToken\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```","events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor constructor() { _disableInitializers(); } ``` ====\",\"details\":\"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\\\"MyToken\\\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122032c981b40e98c6518e9b184e27c95fe99a3d7098e53f36ff2dacd94c9bd8c72c64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122032c981b40e98c6518e9b184e27c95fe99a3d7098e53f36ff2dacd94c9bd8c72c64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"69007:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;69007:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"69007:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:MerkleTreeManager":{"code":"0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122032e9d16aee7ef1e1ea01a3a3f1c5c0af291445a23dac856da5f1d026ea9f88ee64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122032e9d16aee7ef1e1ea01a3a3f1c5c0af291445a23dac856da5f1d026ea9f88ee64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"116124:968:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"116124:968:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116729:81;116793:10;;116729:81;;;160:25:1;;;148:2;133:18;116729:81:0;;;;;;;116273:32;;;;;;:::i;:::-;;:::i;116545:81::-;;;:::i;116241:26::-;;;;;;;116273:32;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116273:32:0;:::o;116545:81::-;116582:7;116608:11;:4;:9;:11::i;:::-;116601:18;;116545:81;:::o;71146:122::-;71203:7;71229:32;71241:5;71248:12;:10;:12::i;:::-;71229:11;:32::i;:::-;71222:39;71146:122;-1:-1:-1;;71146:122:0:o;71386:964::-;71431:34;;:::i;:::-;71490:3;71477:16;;71516:3;71477:10;71503;;:16;71542:3;71529:10;;;:16;71568:3;71555:10;;;:16;71594:3;71581:10;;;:16;71620:3;71607:10;;;:16;71646:3;71633:10;;;:16;71672:3;71659:10;;;:16;71698:3;71685:10;;;:16;71724:3;71711:10;;;:16;71751:4;71737:11;;;:18;71779:4;71765:11;;;:18;71807:4;71793:11;;;:18;71835:4;71821:11;;;:18;71863:4;71849:11;;;:18;71891:4;71877:11;;;:18;71919:4;71905:11;;;:18;71947:4;71933:11;;;:18;71975:4;71961:11;;;:18;72003:4;71989:11;;;:18;72031:4;72017:11;;;:18;72059:4;72045:11;;;:18;72087:4;72073:11;;;:18;72115:4;72101:11;;;:18;72143:4;72129:11;;;:18;72171:4;72157:11;;;:18;72199:4;72185:11;;;:18;72227:4;72213:11;;;:18;72255:4;72241:11;;;:18;72283:4;72269:11;;;:18;72311:4;72297:11;;;:18;72339:4;72325:11;;;:18;71477:7;71386:964::o;70490:589::-;70663:11;;;;70614:16;;;70685:388;69070:2;70705:1;:14;70685:388;;;70771:4;70756:11;;;70755:20;;;70793:12;;;70789:215;;70863:5;70876:1;70863:15;;;;;;;:::i;:::-;;;70846:43;;;;;;909:19:1;;;;944:12;;937:28;;;981:12;;70846:43:0;;;;;;;;;;;;70836:54;;;;;;70825:65;;70789:215;;;70967:8;70977:7;70985:1;70977:10;;;;;;;:::i;:::-;;;;;70950:38;;;;;;;;909:19:1;;;953:2;944:12;;937:28;990:2;981:12;;752:247;70950:38:0;;;;;;;;;;;;;70940:49;;;;;;70929:60;;70789:215;-1:-1:-1;71045:3:0;;70685:388;;;;70636:443;70490:589;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;563:184::-;615:77;612:1;605:88;712:4;709:1;702:15;736:4;733:1;726:15","abiDefinition":[{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"root()":{"notice":"Calculates and returns tree's current root"}},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"MerkleTreeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"count()":"06661abd","historicalRoots(uint256)":"7ea97f40","root()":"ebf0c717","tree()":"fd54b228"}},"solidity/Home.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507ff668f5b5f6099edd5845f8951dd7eaca2b6193823343e3386d623462731f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220507ff668f5b5f6099edd5845f8951dd7eaca2b6193823343e3386d623462731f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"81448:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;81448:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"81448:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/Home.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208d0b12f0092953f7cabf5de746cbb5ee40d542852e361f4b715f3bb6c7a951a664736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208d0b12f0092953f7cabf5de746cbb5ee40d542852e361f4b715f3bb6c7a951a664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"35642:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;35642:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"35642:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:SystemContract":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"SystemContract\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b"}},"solidity/Home.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122064d0c81f40cd6947972ebb8451702ae66bd4d98b852c09adbce7930c7d6189d564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122064d0c81f40cd6947972ebb8451702ae66bd4d98b852c09adbce7930c7d6189d564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"89422:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;89422:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"89422:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202d2bf16beb89b80167034b16fe5667642e695a1bdc96830cc9d5c528b112a31a64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202d2bf16beb89b80167034b16fe5667642e695a1bdc96830cc9d5c528b112a31a64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"86421:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;86421:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"86421:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a8fe757644021462d97ec3a29541a08b6f3014908c27607b430ac007c5a339f064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a8fe757644021462d97ec3a29541a08b6f3014908c27607b430ac007c5a339f064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"77031:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;77031:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"77031:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{}},"solidity/Home.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212209b09e3cec3dad3609669ed2c818a86ed95b44328b4061647e48d11b465c3cd8464736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212209b09e3cec3dad3609669ed2c818a86ed95b44328b4061647e48d11b465c3cd8464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"88:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;88:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"88:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2601:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2601:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/Home.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212201b482fe10d1ef874b5b4f4278fc44676f2b0c3af160b101d71eb7da4a81e5da364736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212201b482fe10d1ef874b5b4f4278fc44676f2b0c3af160b101d71eb7da4a81e5da364736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title Home\n * @author Illusory Systems Inc.\n * @notice Accepts messages to be dispatched to remote chains,\n * constructs a Merkle tree of the messages,\n * and accepts signatures from a bonded Updater\n * which notarize the Merkle tree roots.\n * Accepts submissions of fraudulent signatures\n * by the Updater and slashes the Updater in this case.\n */\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50:33;;82:1;50:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;50:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/Home.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/Home.sol\":{\"keccak256\":\"0x410bcb9294ab77edb46f3fc16f66825ce22bd3c57b8dab4f807368a19b92bb3f\",\"urls\":[\"bzz-raw://0e5e9594de51261e8106c9b1cae97042d494a470c623e418c484da483c7ac6f3\",\"dweb:/ipfs/QmaCXeReAVFbdHxbmGRz5wZjZUYQMyGm8fiHCKdF87Q41f\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file diff --git a/core/contracts/home/icaller_generated.go b/core/contracts/home/icaller_generated.go index 0ef9663c01..dbc1050493 100644 --- a/core/contracts/home/icaller_generated.go +++ b/core/contracts/home/icaller_generated.go @@ -19,10 +19,30 @@ type IHomeCaller interface { // // Solidity: function VERSION() view returns(uint8) VERSION(opts *bind.CallOpts) (uint8, error) + // AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. + // + // Solidity: function allGuards() view returns(address[]) + AllGuards(opts *bind.CallOpts) ([]common.Address, error) + // AllNotaries is a free data retrieval call binding the contract method 0x9817e315. + // + // Solidity: function allNotaries() view returns(address[]) + AllNotaries(opts *bind.CallOpts) ([]common.Address, error) // Count is a free data retrieval call binding the contract method 0x06661abd. // // Solidity: function count() view returns(uint256) Count(opts *bind.CallOpts) (*big.Int, error) + // GetGuard is a free data retrieval call binding the contract method 0x629ddf69. + // + // Solidity: function getGuard(uint256 _index) view returns(address) + GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) + // GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. + // + // Solidity: function getNotary(uint256 _index) view returns(address) + GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) + // GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. + // + // Solidity: function guardsAmount() view returns(uint256) + GuardsAmount(opts *bind.CallOpts) (*big.Int, error) // HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. // // Solidity: function historicalRoots(uint256 ) view returns(bytes32) @@ -35,6 +55,10 @@ type IHomeCaller interface { // // Solidity: function nonce() view returns(uint32) Nonce(opts *bind.CallOpts) (uint32, error) + // NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. + // + // Solidity: function notariesAmount() view returns(uint256) + NotariesAmount(opts *bind.CallOpts) (*big.Int, error) // Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // // Solidity: function owner() view returns(address) @@ -62,10 +86,6 @@ type IHomeCaller interface { // // Solidity: function tree() view returns(uint256 count) Tree(opts *bind.CallOpts) (*big.Int, error) - // Updater is a free data retrieval call binding the contract method 0xdf034cd0. - // - // Solidity: function updater() view returns(address) - Updater(opts *bind.CallOpts) (common.Address, error) // UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. // // Solidity: function updaterManager() view returns(address) diff --git a/core/contracts/home/mocks/i_home.go b/core/contracts/home/mocks/i_home.go index f50c7bfc9d..b5912a7217 100644 --- a/core/contracts/home/mocks/i_home.go +++ b/core/contracts/home/mocks/i_home.go @@ -38,6 +38,52 @@ func (_m *IHome) Address() common.Address { return r0 } +// AllGuards provides a mock function with given fields: opts +func (_m *IHome) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + var r0 []common.Address + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// AllNotaries provides a mock function with given fields: opts +func (_m *IHome) AllNotaries(opts *bind.CallOpts) ([]common.Address, error) { + ret := _m.Called(opts) + + var r0 []common.Address + if rf, ok := ret.Get(0).(func(*bind.CallOpts) []common.Address); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Count provides a mock function with given fields: opts func (_m *IHome) Count(opts *bind.CallOpts) (*big.Int, error) { ret := _m.Called(opts) @@ -107,16 +153,16 @@ func (_m *IHome) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, l return r0, r1 } -// FilterImproperAttestation provides a mock function with given fields: opts -func (_m *IHome) FilterImproperAttestation(opts *bind.FilterOpts) (*home.HomeImproperAttestationIterator, error) { +// FilterDomainNotaryAdded provides a mock function with given fields: opts +func (_m *IHome) FilterDomainNotaryAdded(opts *bind.FilterOpts) (*home.HomeDomainNotaryAddedIterator, error) { ret := _m.Called(opts) - var r0 *home.HomeImproperAttestationIterator - if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeImproperAttestationIterator); ok { + var r0 *home.HomeDomainNotaryAddedIterator + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeDomainNotaryAddedIterator); ok { r0 = rf(opts) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeImproperAttestationIterator) + r0 = ret.Get(0).(*home.HomeDomainNotaryAddedIterator) } } @@ -130,16 +176,16 @@ func (_m *IHome) FilterImproperAttestation(opts *bind.FilterOpts) (*home.HomeImp return r0, r1 } -// FilterInitialized provides a mock function with given fields: opts -func (_m *IHome) FilterInitialized(opts *bind.FilterOpts) (*home.HomeInitializedIterator, error) { +// FilterDomainNotaryRemoved provides a mock function with given fields: opts +func (_m *IHome) FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*home.HomeDomainNotaryRemovedIterator, error) { ret := _m.Called(opts) - var r0 *home.HomeInitializedIterator - if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeInitializedIterator); ok { + var r0 *home.HomeDomainNotaryRemovedIterator + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeDomainNotaryRemovedIterator); ok { r0 = rf(opts) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeInitializedIterator) + r0 = ret.Get(0).(*home.HomeDomainNotaryRemovedIterator) } } @@ -153,16 +199,85 @@ func (_m *IHome) FilterInitialized(opts *bind.FilterOpts) (*home.HomeInitialized return r0, r1 } -// FilterNewUpdater provides a mock function with given fields: opts -func (_m *IHome) FilterNewUpdater(opts *bind.FilterOpts) (*home.HomeNewUpdaterIterator, error) { +// FilterGuardAdded provides a mock function with given fields: opts +func (_m *IHome) FilterGuardAdded(opts *bind.FilterOpts) (*home.HomeGuardAddedIterator, error) { ret := _m.Called(opts) - var r0 *home.HomeNewUpdaterIterator - if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeNewUpdaterIterator); ok { + var r0 *home.HomeGuardAddedIterator + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeGuardAddedIterator); ok { r0 = rf(opts) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeNewUpdaterIterator) + r0 = ret.Get(0).(*home.HomeGuardAddedIterator) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FilterGuardRemoved provides a mock function with given fields: opts +func (_m *IHome) FilterGuardRemoved(opts *bind.FilterOpts) (*home.HomeGuardRemovedIterator, error) { + ret := _m.Called(opts) + + var r0 *home.HomeGuardRemovedIterator + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeGuardRemovedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*home.HomeGuardRemovedIterator) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FilterImproperAttestation provides a mock function with given fields: opts +func (_m *IHome) FilterImproperAttestation(opts *bind.FilterOpts) (*home.HomeImproperAttestationIterator, error) { + ret := _m.Called(opts) + + var r0 *home.HomeImproperAttestationIterator + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeImproperAttestationIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*home.HomeImproperAttestationIterator) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.FilterOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FilterInitialized provides a mock function with given fields: opts +func (_m *IHome) FilterInitialized(opts *bind.FilterOpts) (*home.HomeInitializedIterator, error) { + ret := _m.Called(opts) + + var r0 *home.HomeInitializedIterator + if rf, ok := ret.Get(0).(func(*bind.FilterOpts) *home.HomeInitializedIterator); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*home.HomeInitializedIterator) } } @@ -222,22 +337,22 @@ func (_m *IHome) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner return r0, r1 } -// FilterUpdate provides a mock function with given fields: opts, homeDomain, nonce, root -func (_m *IHome) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*home.HomeUpdateIterator, error) { - ret := _m.Called(opts, homeDomain, nonce, root) +// FilterUpdaterSlashed provides a mock function with given fields: opts, updater, reporter +func (_m *IHome) FilterUpdaterSlashed(opts *bind.FilterOpts, updater []common.Address, reporter []common.Address) (*home.HomeUpdaterSlashedIterator, error) { + ret := _m.Called(opts, updater, reporter) - var r0 *home.HomeUpdateIterator - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []uint32, []uint32, [][32]byte) *home.HomeUpdateIterator); ok { - r0 = rf(opts, homeDomain, nonce, root) + var r0 *home.HomeUpdaterSlashedIterator + if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *home.HomeUpdaterSlashedIterator); ok { + r0 = rf(opts, updater, reporter) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeUpdateIterator) + r0 = ret.Get(0).(*home.HomeUpdaterSlashedIterator) } } var r1 error - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []uint32, []uint32, [][32]byte) error); ok { - r1 = rf(opts, homeDomain, nonce, root) + if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { + r1 = rf(opts, updater, reporter) } else { r1 = ret.Error(1) } @@ -245,22 +360,68 @@ func (_m *IHome) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce return r0, r1 } -// FilterUpdaterSlashed provides a mock function with given fields: opts, updater, reporter -func (_m *IHome) FilterUpdaterSlashed(opts *bind.FilterOpts, updater []common.Address, reporter []common.Address) (*home.HomeUpdaterSlashedIterator, error) { - ret := _m.Called(opts, updater, reporter) +// GetGuard provides a mock function with given fields: opts, _index +func (_m *IHome) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + ret := _m.Called(opts, _index) - var r0 *home.HomeUpdaterSlashedIterator - if rf, ok := ret.Get(0).(func(*bind.FilterOpts, []common.Address, []common.Address) *home.HomeUpdaterSlashedIterator); ok { - r0 = rf(opts, updater, reporter) + var r0 common.Address + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) common.Address); ok { + r0 = rf(opts, _index) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeUpdaterSlashedIterator) + r0 = ret.Get(0).(common.Address) } } var r1 error - if rf, ok := ret.Get(1).(func(*bind.FilterOpts, []common.Address, []common.Address) error); ok { - r1 = rf(opts, updater, reporter) + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int) error); ok { + r1 = rf(opts, _index) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNotary provides a mock function with given fields: opts, _index +func (_m *IHome) GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + ret := _m.Called(opts, _index) + + var r0 common.Address + if rf, ok := ret.Get(0).(func(*bind.CallOpts, *big.Int) common.Address); ok { + r0 = rf(opts, _index) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.CallOpts, *big.Int) error); ok { + r1 = rf(opts, _index) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GuardsAmount provides a mock function with given fields: opts +func (_m *IHome) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + var r0 *big.Int + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) } else { r1 = ret.Error(1) } @@ -402,6 +563,29 @@ func (_m *IHome) Nonce(opts *bind.CallOpts) (uint32, error) { return r0, r1 } +// NotariesAmount provides a mock function with given fields: opts +func (_m *IHome) NotariesAmount(opts *bind.CallOpts) (*big.Int, error) { + ret := _m.Called(opts) + + var r0 *big.Int + if rf, ok := ret.Get(0).(func(*bind.CallOpts) *big.Int); ok { + r0 = rf(opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { + r1 = rf(opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Owner provides a mock function with given fields: opts func (_m *IHome) Owner(opts *bind.CallOpts) (common.Address, error) { ret := _m.Called(opts) @@ -448,16 +632,16 @@ func (_m *IHome) ParseDispatch(log types.Log) (*home.HomeDispatch, error) { return r0, r1 } -// ParseImproperAttestation provides a mock function with given fields: log -func (_m *IHome) ParseImproperAttestation(log types.Log) (*home.HomeImproperAttestation, error) { +// ParseDomainNotaryAdded provides a mock function with given fields: log +func (_m *IHome) ParseDomainNotaryAdded(log types.Log) (*home.HomeDomainNotaryAdded, error) { ret := _m.Called(log) - var r0 *home.HomeImproperAttestation - if rf, ok := ret.Get(0).(func(types.Log) *home.HomeImproperAttestation); ok { + var r0 *home.HomeDomainNotaryAdded + if rf, ok := ret.Get(0).(func(types.Log) *home.HomeDomainNotaryAdded); ok { r0 = rf(log) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeImproperAttestation) + r0 = ret.Get(0).(*home.HomeDomainNotaryAdded) } } @@ -471,16 +655,16 @@ func (_m *IHome) ParseImproperAttestation(log types.Log) (*home.HomeImproperAtte return r0, r1 } -// ParseInitialized provides a mock function with given fields: log -func (_m *IHome) ParseInitialized(log types.Log) (*home.HomeInitialized, error) { +// ParseDomainNotaryRemoved provides a mock function with given fields: log +func (_m *IHome) ParseDomainNotaryRemoved(log types.Log) (*home.HomeDomainNotaryRemoved, error) { ret := _m.Called(log) - var r0 *home.HomeInitialized - if rf, ok := ret.Get(0).(func(types.Log) *home.HomeInitialized); ok { + var r0 *home.HomeDomainNotaryRemoved + if rf, ok := ret.Get(0).(func(types.Log) *home.HomeDomainNotaryRemoved); ok { r0 = rf(log) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeInitialized) + r0 = ret.Get(0).(*home.HomeDomainNotaryRemoved) } } @@ -494,16 +678,16 @@ func (_m *IHome) ParseInitialized(log types.Log) (*home.HomeInitialized, error) return r0, r1 } -// ParseNewUpdater provides a mock function with given fields: log -func (_m *IHome) ParseNewUpdater(log types.Log) (*home.HomeNewUpdater, error) { +// ParseGuardAdded provides a mock function with given fields: log +func (_m *IHome) ParseGuardAdded(log types.Log) (*home.HomeGuardAdded, error) { ret := _m.Called(log) - var r0 *home.HomeNewUpdater - if rf, ok := ret.Get(0).(func(types.Log) *home.HomeNewUpdater); ok { + var r0 *home.HomeGuardAdded + if rf, ok := ret.Get(0).(func(types.Log) *home.HomeGuardAdded); ok { r0 = rf(log) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeNewUpdater) + r0 = ret.Get(0).(*home.HomeGuardAdded) } } @@ -517,16 +701,16 @@ func (_m *IHome) ParseNewUpdater(log types.Log) (*home.HomeNewUpdater, error) { return r0, r1 } -// ParseNewUpdaterManager provides a mock function with given fields: log -func (_m *IHome) ParseNewUpdaterManager(log types.Log) (*home.HomeNewUpdaterManager, error) { +// ParseGuardRemoved provides a mock function with given fields: log +func (_m *IHome) ParseGuardRemoved(log types.Log) (*home.HomeGuardRemoved, error) { ret := _m.Called(log) - var r0 *home.HomeNewUpdaterManager - if rf, ok := ret.Get(0).(func(types.Log) *home.HomeNewUpdaterManager); ok { + var r0 *home.HomeGuardRemoved + if rf, ok := ret.Get(0).(func(types.Log) *home.HomeGuardRemoved); ok { r0 = rf(log) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeNewUpdaterManager) + r0 = ret.Get(0).(*home.HomeGuardRemoved) } } @@ -540,16 +724,62 @@ func (_m *IHome) ParseNewUpdaterManager(log types.Log) (*home.HomeNewUpdaterMana return r0, r1 } -// ParseOwnershipTransferred provides a mock function with given fields: log -func (_m *IHome) ParseOwnershipTransferred(log types.Log) (*home.HomeOwnershipTransferred, error) { +// ParseImproperAttestation provides a mock function with given fields: log +func (_m *IHome) ParseImproperAttestation(log types.Log) (*home.HomeImproperAttestation, error) { ret := _m.Called(log) - var r0 *home.HomeOwnershipTransferred - if rf, ok := ret.Get(0).(func(types.Log) *home.HomeOwnershipTransferred); ok { + var r0 *home.HomeImproperAttestation + if rf, ok := ret.Get(0).(func(types.Log) *home.HomeImproperAttestation); ok { r0 = rf(log) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeOwnershipTransferred) + r0 = ret.Get(0).(*home.HomeImproperAttestation) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ParseInitialized provides a mock function with given fields: log +func (_m *IHome) ParseInitialized(log types.Log) (*home.HomeInitialized, error) { + ret := _m.Called(log) + + var r0 *home.HomeInitialized + if rf, ok := ret.Get(0).(func(types.Log) *home.HomeInitialized); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*home.HomeInitialized) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(types.Log) error); ok { + r1 = rf(log) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ParseNewUpdaterManager provides a mock function with given fields: log +func (_m *IHome) ParseNewUpdaterManager(log types.Log) (*home.HomeNewUpdaterManager, error) { + ret := _m.Called(log) + + var r0 *home.HomeNewUpdaterManager + if rf, ok := ret.Get(0).(func(types.Log) *home.HomeNewUpdaterManager); ok { + r0 = rf(log) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*home.HomeNewUpdaterManager) } } @@ -563,16 +793,16 @@ func (_m *IHome) ParseOwnershipTransferred(log types.Log) (*home.HomeOwnershipTr return r0, r1 } -// ParseUpdate provides a mock function with given fields: log -func (_m *IHome) ParseUpdate(log types.Log) (*home.HomeUpdate, error) { +// ParseOwnershipTransferred provides a mock function with given fields: log +func (_m *IHome) ParseOwnershipTransferred(log types.Log) (*home.HomeOwnershipTransferred, error) { ret := _m.Called(log) - var r0 *home.HomeUpdate - if rf, ok := ret.Get(0).(func(types.Log) *home.HomeUpdate); ok { + var r0 *home.HomeOwnershipTransferred + if rf, ok := ret.Get(0).(func(types.Log) *home.HomeOwnershipTransferred); ok { r0 = rf(log) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*home.HomeUpdate) + r0 = ret.Get(0).(*home.HomeOwnershipTransferred) } } @@ -863,29 +1093,6 @@ func (_m *IHome) Tree(opts *bind.CallOpts) (*big.Int, error) { return r0, r1 } -// Updater provides a mock function with given fields: opts -func (_m *IHome) Updater(opts *bind.CallOpts) (common.Address, error) { - ret := _m.Called(opts) - - var r0 common.Address - if rf, ok := ret.Get(0).(func(*bind.CallOpts) common.Address); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(common.Address) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*bind.CallOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // UpdaterManager provides a mock function with given fields: opts func (_m *IHome) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { ret := _m.Called(opts) @@ -953,12 +1160,12 @@ func (_m *IHome) WatchDispatch(opts *bind.WatchOpts, sink chan<- *home.HomeDispa return r0, r1 } -// WatchImproperAttestation provides a mock function with given fields: opts, sink -func (_m *IHome) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *home.HomeImproperAttestation) (event.Subscription, error) { +// WatchDomainNotaryAdded provides a mock function with given fields: opts, sink +func (_m *IHome) WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *home.HomeDomainNotaryAdded) (event.Subscription, error) { ret := _m.Called(opts, sink) var r0 event.Subscription - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeImproperAttestation) event.Subscription); ok { + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeDomainNotaryAdded) event.Subscription); ok { r0 = rf(opts, sink) } else { if ret.Get(0) != nil { @@ -967,7 +1174,7 @@ func (_m *IHome) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *hom } var r1 error - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeImproperAttestation) error); ok { + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeDomainNotaryAdded) error); ok { r1 = rf(opts, sink) } else { r1 = ret.Error(1) @@ -976,12 +1183,12 @@ func (_m *IHome) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *hom return r0, r1 } -// WatchInitialized provides a mock function with given fields: opts, sink -func (_m *IHome) WatchInitialized(opts *bind.WatchOpts, sink chan<- *home.HomeInitialized) (event.Subscription, error) { +// WatchDomainNotaryRemoved provides a mock function with given fields: opts, sink +func (_m *IHome) WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *home.HomeDomainNotaryRemoved) (event.Subscription, error) { ret := _m.Called(opts, sink) var r0 event.Subscription - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeInitialized) event.Subscription); ok { + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeDomainNotaryRemoved) event.Subscription); ok { r0 = rf(opts, sink) } else { if ret.Get(0) != nil { @@ -990,7 +1197,7 @@ func (_m *IHome) WatchInitialized(opts *bind.WatchOpts, sink chan<- *home.HomeIn } var r1 error - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeInitialized) error); ok { + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeDomainNotaryRemoved) error); ok { r1 = rf(opts, sink) } else { r1 = ret.Error(1) @@ -999,12 +1206,12 @@ func (_m *IHome) WatchInitialized(opts *bind.WatchOpts, sink chan<- *home.HomeIn return r0, r1 } -// WatchNewUpdater provides a mock function with given fields: opts, sink -func (_m *IHome) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *home.HomeNewUpdater) (event.Subscription, error) { +// WatchGuardAdded provides a mock function with given fields: opts, sink +func (_m *IHome) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *home.HomeGuardAdded) (event.Subscription, error) { ret := _m.Called(opts, sink) var r0 event.Subscription - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeNewUpdater) event.Subscription); ok { + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeGuardAdded) event.Subscription); ok { r0 = rf(opts, sink) } else { if ret.Get(0) != nil { @@ -1013,7 +1220,7 @@ func (_m *IHome) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *home.HomeNew } var r1 error - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeNewUpdater) error); ok { + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeGuardAdded) error); ok { r1 = rf(opts, sink) } else { r1 = ret.Error(1) @@ -1022,12 +1229,12 @@ func (_m *IHome) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *home.HomeNew return r0, r1 } -// WatchNewUpdaterManager provides a mock function with given fields: opts, sink -func (_m *IHome) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *home.HomeNewUpdaterManager) (event.Subscription, error) { +// WatchGuardRemoved provides a mock function with given fields: opts, sink +func (_m *IHome) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *home.HomeGuardRemoved) (event.Subscription, error) { ret := _m.Called(opts, sink) var r0 event.Subscription - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeNewUpdaterManager) event.Subscription); ok { + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeGuardRemoved) event.Subscription); ok { r0 = rf(opts, sink) } else { if ret.Get(0) != nil { @@ -1036,7 +1243,7 @@ func (_m *IHome) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *home. } var r1 error - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeNewUpdaterManager) error); ok { + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeGuardRemoved) error); ok { r1 = rf(opts, sink) } else { r1 = ret.Error(1) @@ -1045,13 +1252,13 @@ func (_m *IHome) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *home. return r0, r1 } -// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, previousOwner, newOwner -func (_m *IHome) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *home.HomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - ret := _m.Called(opts, sink, previousOwner, newOwner) +// WatchImproperAttestation provides a mock function with given fields: opts, sink +func (_m *IHome) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *home.HomeImproperAttestation) (event.Subscription, error) { + ret := _m.Called(opts, sink) var r0 event.Subscription - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { - r0 = rf(opts, sink, previousOwner, newOwner) + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeImproperAttestation) event.Subscription); ok { + r0 = rf(opts, sink) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(event.Subscription) @@ -1059,8 +1266,8 @@ func (_m *IHome) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ho } var r1 error - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeOwnershipTransferred, []common.Address, []common.Address) error); ok { - r1 = rf(opts, sink, previousOwner, newOwner) + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeImproperAttestation) error); ok { + r1 = rf(opts, sink) } else { r1 = ret.Error(1) } @@ -1068,13 +1275,13 @@ func (_m *IHome) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ho return r0, r1 } -// WatchUpdate provides a mock function with given fields: opts, sink, homeDomain, nonce, root -func (_m *IHome) WatchUpdate(opts *bind.WatchOpts, sink chan<- *home.HomeUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { - ret := _m.Called(opts, sink, homeDomain, nonce, root) +// WatchInitialized provides a mock function with given fields: opts, sink +func (_m *IHome) WatchInitialized(opts *bind.WatchOpts, sink chan<- *home.HomeInitialized) (event.Subscription, error) { + ret := _m.Called(opts, sink) var r0 event.Subscription - if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeUpdate, []uint32, []uint32, [][32]byte) event.Subscription); ok { - r0 = rf(opts, sink, homeDomain, nonce, root) + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeInitialized) event.Subscription); ok { + r0 = rf(opts, sink) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(event.Subscription) @@ -1082,8 +1289,54 @@ func (_m *IHome) WatchUpdate(opts *bind.WatchOpts, sink chan<- *home.HomeUpdate, } var r1 error - if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeUpdate, []uint32, []uint32, [][32]byte) error); ok { - r1 = rf(opts, sink, homeDomain, nonce, root) + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeInitialized) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// WatchNewUpdaterManager provides a mock function with given fields: opts, sink +func (_m *IHome) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *home.HomeNewUpdaterManager) (event.Subscription, error) { + ret := _m.Called(opts, sink) + + var r0 event.Subscription + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeNewUpdaterManager) event.Subscription); ok { + r0 = rf(opts, sink) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeNewUpdaterManager) error); ok { + r1 = rf(opts, sink) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// WatchOwnershipTransferred provides a mock function with given fields: opts, sink, previousOwner, newOwner +func (_m *IHome) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *home.HomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + ret := _m.Called(opts, sink, previousOwner, newOwner) + + var r0 event.Subscription + if rf, ok := ret.Get(0).(func(*bind.WatchOpts, chan<- *home.HomeOwnershipTransferred, []common.Address, []common.Address) event.Subscription); ok { + r0 = rf(opts, sink, previousOwner, newOwner) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(event.Subscription) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*bind.WatchOpts, chan<- *home.HomeOwnershipTransferred, []common.Address, []common.Address) error); ok { + r1 = rf(opts, sink, previousOwner, newOwner) } else { r1 = ret.Error(1) } diff --git a/core/contracts/replicamanager/replicamanager.abigen.go b/core/contracts/replicamanager/replicamanager.abigen.go index 85f9ea1926..f843202012 100644 --- a/core/contracts/replicamanager/replicamanager.abigen.go +++ b/core/contracts/replicamanager/replicamanager.abigen.go @@ -28,10 +28,312 @@ var ( _ = event.NewSubscription ) +// AbstractGuardRegistryMetaData contains all meta data concerning the AbstractGuardRegistry contract. +var AbstractGuardRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractGuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractGuardRegistryMetaData.ABI instead. +var AbstractGuardRegistryABI = AbstractGuardRegistryMetaData.ABI + +// AbstractGuardRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractGuardRegistry struct { + AbstractGuardRegistryCaller // Read-only binding to the contract + AbstractGuardRegistryTransactor // Write-only binding to the contract + AbstractGuardRegistryFilterer // Log filterer for contract events +} + +// AbstractGuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractGuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractGuardRegistrySession struct { + Contract *AbstractGuardRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractGuardRegistryCallerSession struct { + Contract *AbstractGuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractGuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractGuardRegistryTransactorSession struct { + Contract *AbstractGuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractGuardRegistryRaw struct { + Contract *AbstractGuardRegistry // Generic contract binding to access the raw methods on +} + +// AbstractGuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCallerRaw struct { + Contract *AbstractGuardRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractGuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactorRaw struct { + Contract *AbstractGuardRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractGuardRegistry creates a new instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistry(address common.Address, backend bind.ContractBackend) (*AbstractGuardRegistry, error) { + contract, err := bindAbstractGuardRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractGuardRegistry{AbstractGuardRegistryCaller: AbstractGuardRegistryCaller{contract: contract}, AbstractGuardRegistryTransactor: AbstractGuardRegistryTransactor{contract: contract}, AbstractGuardRegistryFilterer: AbstractGuardRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractGuardRegistryCaller creates a new read-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractGuardRegistryCaller, error) { + contract, err := bindAbstractGuardRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryCaller{contract: contract}, nil +} + +// NewAbstractGuardRegistryTransactor creates a new write-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractGuardRegistryTransactor, error) { + contract, err := bindAbstractGuardRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryTransactor{contract: contract}, nil +} + +// NewAbstractGuardRegistryFilterer creates a new log filterer instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractGuardRegistryFilterer, error) { + contract, err := bindAbstractGuardRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryFilterer{contract: contract}, nil +} + +// bindAbstractGuardRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractGuardRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transact(opts, method, params...) +} + +// AbstractNotaryRegistryMetaData contains all meta data concerning the AbstractNotaryRegistry contract. +var AbstractNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractNotaryRegistryMetaData.ABI instead. +var AbstractNotaryRegistryABI = AbstractNotaryRegistryMetaData.ABI + +// AbstractNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractNotaryRegistry struct { + AbstractNotaryRegistryCaller // Read-only binding to the contract + AbstractNotaryRegistryTransactor // Write-only binding to the contract + AbstractNotaryRegistryFilterer // Log filterer for contract events +} + +// AbstractNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractNotaryRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractNotaryRegistrySession struct { + Contract *AbstractNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractNotaryRegistryCallerSession struct { + Contract *AbstractNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractNotaryRegistryTransactorSession struct { + Contract *AbstractNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractNotaryRegistryRaw struct { + Contract *AbstractNotaryRegistry // Generic contract binding to access the raw methods on +} + +// AbstractNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCallerRaw struct { + Contract *AbstractNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactorRaw struct { + Contract *AbstractNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractNotaryRegistry creates a new instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistry(address common.Address, backend bind.ContractBackend) (*AbstractNotaryRegistry, error) { + contract, err := bindAbstractNotaryRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistry{AbstractNotaryRegistryCaller: AbstractNotaryRegistryCaller{contract: contract}, AbstractNotaryRegistryTransactor: AbstractNotaryRegistryTransactor{contract: contract}, AbstractNotaryRegistryFilterer: AbstractNotaryRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractNotaryRegistryCaller creates a new read-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractNotaryRegistryCaller, error) { + contract, err := bindAbstractNotaryRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryCaller{contract: contract}, nil +} + +// NewAbstractNotaryRegistryTransactor creates a new write-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractNotaryRegistryTransactor, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryTransactor{contract: contract}, nil +} + +// NewAbstractNotaryRegistryFilterer creates a new log filterer instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractNotaryRegistryFilterer, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryFilterer{contract: contract}, nil +} + +// bindAbstractNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractNotaryRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transact(opts, method, params...) +} + // AddressUpgradeableMetaData contains all meta data concerning the AddressUpgradeable contract. var AddressUpgradeableMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204b230d9c26cd1dd9a151d1741f1f6552f668447fd46dcf49d3be4505c7468ad264736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a0a83d0287d6b3bfd8e50d4364bff6024fca94f4f44158c6fff6d7bd0e52ba2664736f6c634300080d0033", } // AddressUpgradeableABI is the input ABI used to generate the binding from. @@ -204,7 +506,7 @@ func (_AddressUpgradeable *AddressUpgradeableTransactorRaw) Transact(opts *bind. // AttestationMetaData contains all meta data concerning the Attestation contract. var AttestationMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ebcf0879a676dd3fd02954c3a843377d2a33085a237b62601f0f050cc9209cd164736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220791cba0f456ea113690031c6a55afc51fd8de048f41da85b89f956ddcb6fa60464736f6c634300080d0033", } // AttestationABI is the input ABI used to generate the binding from. @@ -377,7 +679,7 @@ func (_Attestation *AttestationTransactorRaw) Transact(opts *bind.TransactOpts, // AuthMetaData contains all meta data concerning the Auth contract. var AuthMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122014bcd9f069378f066068e7d01c733591f31339484b7e3bbd4949dc7a5a76129e64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122092ab118aab8488d5aac04736bb7d595802a34a19f2c05876b46f3599af7f388964736f6c634300080d0033", } // AuthABI is the input ABI used to generate the binding from. @@ -547,157 +849,6 @@ func (_Auth *AuthTransactorRaw) Transact(opts *bind.TransactOpts, method string, return _Auth.Contract.contract.Transact(opts, method, params...) } -// AuthManagerMetaData contains all meta data concerning the AuthManager contract. -var AuthManagerMetaData = &bind.MetaData{ - ABI: "[]", -} - -// AuthManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use AuthManagerMetaData.ABI instead. -var AuthManagerABI = AuthManagerMetaData.ABI - -// AuthManager is an auto generated Go binding around an Ethereum contract. -type AuthManager struct { - AuthManagerCaller // Read-only binding to the contract - AuthManagerTransactor // Write-only binding to the contract - AuthManagerFilterer // Log filterer for contract events -} - -// AuthManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type AuthManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type AuthManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type AuthManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type AuthManagerSession struct { - Contract *AuthManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type AuthManagerCallerSession struct { - Contract *AuthManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// AuthManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type AuthManagerTransactorSession struct { - Contract *AuthManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type AuthManagerRaw struct { - Contract *AuthManager // Generic contract binding to access the raw methods on -} - -// AuthManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type AuthManagerCallerRaw struct { - Contract *AuthManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// AuthManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type AuthManagerTransactorRaw struct { - Contract *AuthManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewAuthManager creates a new instance of AuthManager, bound to a specific deployed contract. -func NewAuthManager(address common.Address, backend bind.ContractBackend) (*AuthManager, error) { - contract, err := bindAuthManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &AuthManager{AuthManagerCaller: AuthManagerCaller{contract: contract}, AuthManagerTransactor: AuthManagerTransactor{contract: contract}, AuthManagerFilterer: AuthManagerFilterer{contract: contract}}, nil -} - -// NewAuthManagerCaller creates a new read-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerCaller(address common.Address, caller bind.ContractCaller) (*AuthManagerCaller, error) { - contract, err := bindAuthManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &AuthManagerCaller{contract: contract}, nil -} - -// NewAuthManagerTransactor creates a new write-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*AuthManagerTransactor, error) { - contract, err := bindAuthManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &AuthManagerTransactor{contract: contract}, nil -} - -// NewAuthManagerFilterer creates a new log filterer instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*AuthManagerFilterer, error) { - contract, err := bindAuthManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &AuthManagerFilterer{contract: contract}, nil -} - -// bindAuthManager binds a generic wrapper to an already deployed contract. -func bindAuthManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(AuthManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.AuthManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transact(opts, method, params...) -} - // ContextUpgradeableMetaData contains all meta data concerning the ContextUpgradeable contract. var ContextUpgradeableMetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", @@ -986,7 +1137,7 @@ func (_ContextUpgradeable *ContextUpgradeableFilterer) ParseInitialized(log type // ECDSAMetaData contains all meta data concerning the ECDSA contract. var ECDSAMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122014c25ba61171c79b0e1125228a2b266115edc5990fe5f425e4df2e44aed43d8864736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220252f8e62e2ff652a2d9331a32227eef4613c8a897e3a7cfac4e0bc0711ae188764736f6c634300080d0033", } // ECDSAABI is the input ABI used to generate the binding from. @@ -1156,23 +1307,23 @@ func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method strin return _ECDSA.Contract.contract.Transact(opts, method, params...) } -// HeaderMetaData contains all meta data concerning the Header contract. -var HeaderMetaData = &bind.MetaData{ +// EnumerableSetMetaData contains all meta data concerning the EnumerableSet contract. +var EnumerableSetMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122026e0c7d056e7f2e1ee28e6b78f5c05e06568f5bc13bbca2169f0138f08a4256764736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122055df74093a3725090dcf96105015e23e52964297e1a2529f3062573bee005b4f64736f6c634300080d0033", } -// HeaderABI is the input ABI used to generate the binding from. -// Deprecated: Use HeaderMetaData.ABI instead. -var HeaderABI = HeaderMetaData.ABI +// EnumerableSetABI is the input ABI used to generate the binding from. +// Deprecated: Use EnumerableSetMetaData.ABI instead. +var EnumerableSetABI = EnumerableSetMetaData.ABI -// HeaderBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HeaderMetaData.Bin instead. -var HeaderBin = HeaderMetaData.Bin +// EnumerableSetBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use EnumerableSetMetaData.Bin instead. +var EnumerableSetBin = EnumerableSetMetaData.Bin -// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. -func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { - parsed, err := HeaderMetaData.GetAbi() +// DeployEnumerableSet deploys a new Ethereum contract, binding an instance of EnumerableSet to it. +func DeployEnumerableSet(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *EnumerableSet, error) { + parsed, err := EnumerableSetMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1180,111 +1331,111 @@ func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EnumerableSetBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil + return address, tx, &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// Header is an auto generated Go binding around an Ethereum contract. -type Header struct { - HeaderCaller // Read-only binding to the contract - HeaderTransactor // Write-only binding to the contract - HeaderFilterer // Log filterer for contract events +// EnumerableSet is an auto generated Go binding around an Ethereum contract. +type EnumerableSet struct { + EnumerableSetCaller // Read-only binding to the contract + EnumerableSetTransactor // Write-only binding to the contract + EnumerableSetFilterer // Log filterer for contract events } -// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. -type HeaderCaller struct { +// EnumerableSetCaller is an auto generated read-only Go binding around an Ethereum contract. +type EnumerableSetCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HeaderTransactor struct { +// EnumerableSetTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EnumerableSetTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HeaderFilterer struct { +// EnumerableSetFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EnumerableSetFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderSession is an auto generated Go binding around an Ethereum contract, +// EnumerableSetSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type HeaderSession struct { - Contract *Header // Generic contract binding to set the session for +type EnumerableSetSession struct { + Contract *EnumerableSet // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// EnumerableSetCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type HeaderCallerSession struct { - Contract *HeaderCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type EnumerableSetCallerSession struct { + Contract *EnumerableSetCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// EnumerableSetTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type HeaderTransactorSession struct { - Contract *HeaderTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type EnumerableSetTransactorSession struct { + Contract *EnumerableSetTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. -type HeaderRaw struct { - Contract *Header // Generic contract binding to access the raw methods on +// EnumerableSetRaw is an auto generated low-level Go binding around an Ethereum contract. +type EnumerableSetRaw struct { + Contract *EnumerableSet // Generic contract binding to access the raw methods on } -// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HeaderCallerRaw struct { - Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on +// EnumerableSetCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EnumerableSetCallerRaw struct { + Contract *EnumerableSetCaller // Generic read-only contract binding to access the raw methods on } -// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HeaderTransactorRaw struct { - Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on +// EnumerableSetTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EnumerableSetTransactorRaw struct { + Contract *EnumerableSetTransactor // Generic write-only contract binding to access the raw methods on } -// NewHeader creates a new instance of Header, bound to a specific deployed contract. -func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { - contract, err := bindHeader(address, backend, backend, backend) +// NewEnumerableSet creates a new instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSet(address common.Address, backend bind.ContractBackend) (*EnumerableSet, error) { + contract, err := bindEnumerableSet(address, backend, backend, backend) if err != nil { return nil, err } - return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil + return &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. -func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { - contract, err := bindHeader(address, caller, nil, nil) +// NewEnumerableSetCaller creates a new read-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetCaller(address common.Address, caller bind.ContractCaller) (*EnumerableSetCaller, error) { + contract, err := bindEnumerableSet(address, caller, nil, nil) if err != nil { return nil, err } - return &HeaderCaller{contract: contract}, nil + return &EnumerableSetCaller{contract: contract}, nil } -// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. -func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { - contract, err := bindHeader(address, nil, transactor, nil) +// NewEnumerableSetTransactor creates a new write-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetTransactor(address common.Address, transactor bind.ContractTransactor) (*EnumerableSetTransactor, error) { + contract, err := bindEnumerableSet(address, nil, transactor, nil) if err != nil { return nil, err } - return &HeaderTransactor{contract: contract}, nil + return &EnumerableSetTransactor{contract: contract}, nil } -// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. -func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { - contract, err := bindHeader(address, nil, nil, filterer) +// NewEnumerableSetFilterer creates a new log filterer instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetFilterer(address common.Address, filterer bind.ContractFilterer) (*EnumerableSetFilterer, error) { + contract, err := bindEnumerableSet(address, nil, nil, filterer) if err != nil { return nil, err } - return &HeaderFilterer{contract: contract}, nil + return &EnumerableSetFilterer{contract: contract}, nil } -// bindHeader binds a generic wrapper to an already deployed contract. -func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HeaderABI)) +// bindEnumerableSet binds a generic wrapper to an already deployed contract. +func bindEnumerableSet(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(EnumerableSetABI)) if err != nil { return nil, err } @@ -1295,154 +1446,169 @@ func bindHeader(address common.Address, caller bind.ContractCaller, transactor b // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) +func (_EnumerableSet *EnumerableSetRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.EnumerableSetCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transfer(opts) +func (_EnumerableSet *EnumerableSetRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) +func (_EnumerableSet *EnumerableSetRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.contract.Call(opts, result, method, params...) +func (_EnumerableSet *EnumerableSetCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.contract.Transfer(opts) +func (_EnumerableSet *EnumerableSetTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.contract.Transact(opts, method, params...) +func (_EnumerableSet *EnumerableSetTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transact(opts, method, params...) } -// IMessageRecipientMetaData contains all meta data concerning the IMessageRecipient contract. -var IMessageRecipientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_rootTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"handle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "e4d16d62": "handle(uint32,uint32,bytes32,uint256,bytes)", - }, +// GlobalNotaryRegistryMetaData contains all meta data concerning the GlobalNotaryRegistry contract. +var GlobalNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"}]", + Bin: "0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea264697066735822122059157c5b2485f571ff8758df23242344e47615d3b646f3fc4aad08515033245964736f6c634300080d0033", } -// IMessageRecipientABI is the input ABI used to generate the binding from. -// Deprecated: Use IMessageRecipientMetaData.ABI instead. -var IMessageRecipientABI = IMessageRecipientMetaData.ABI +// GlobalNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use GlobalNotaryRegistryMetaData.ABI instead. +var GlobalNotaryRegistryABI = GlobalNotaryRegistryMetaData.ABI -// Deprecated: Use IMessageRecipientMetaData.Sigs instead. -// IMessageRecipientFuncSigs maps the 4-byte function signature to its string representation. -var IMessageRecipientFuncSigs = IMessageRecipientMetaData.Sigs +// GlobalNotaryRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GlobalNotaryRegistryMetaData.Bin instead. +var GlobalNotaryRegistryBin = GlobalNotaryRegistryMetaData.Bin -// IMessageRecipient is an auto generated Go binding around an Ethereum contract. -type IMessageRecipient struct { - IMessageRecipientCaller // Read-only binding to the contract - IMessageRecipientTransactor // Write-only binding to the contract - IMessageRecipientFilterer // Log filterer for contract events +// DeployGlobalNotaryRegistry deploys a new Ethereum contract, binding an instance of GlobalNotaryRegistry to it. +func DeployGlobalNotaryRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GlobalNotaryRegistry, error) { + parsed, err := GlobalNotaryRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GlobalNotaryRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GlobalNotaryRegistry{GlobalNotaryRegistryCaller: GlobalNotaryRegistryCaller{contract: contract}, GlobalNotaryRegistryTransactor: GlobalNotaryRegistryTransactor{contract: contract}, GlobalNotaryRegistryFilterer: GlobalNotaryRegistryFilterer{contract: contract}}, nil } -// IMessageRecipientCaller is an auto generated read-only Go binding around an Ethereum contract. -type IMessageRecipientCaller struct { +// GlobalNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type GlobalNotaryRegistry struct { + GlobalNotaryRegistryCaller // Read-only binding to the contract + GlobalNotaryRegistryTransactor // Write-only binding to the contract + GlobalNotaryRegistryFilterer // Log filterer for contract events +} + +// GlobalNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// IMessageRecipientTransactor is an auto generated write-only Go binding around an Ethereum contract. -type IMessageRecipientTransactor struct { +// GlobalNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// IMessageRecipientFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type IMessageRecipientFilterer struct { +// GlobalNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GlobalNotaryRegistryFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// IMessageRecipientSession is an auto generated Go binding around an Ethereum contract, +// GlobalNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type IMessageRecipientSession struct { - Contract *IMessageRecipient // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type GlobalNotaryRegistrySession struct { + Contract *GlobalNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// IMessageRecipientCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// GlobalNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type IMessageRecipientCallerSession struct { - Contract *IMessageRecipientCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type GlobalNotaryRegistryCallerSession struct { + Contract *GlobalNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// IMessageRecipientTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// GlobalNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type IMessageRecipientTransactorSession struct { - Contract *IMessageRecipientTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type GlobalNotaryRegistryTransactorSession struct { + Contract *GlobalNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// IMessageRecipientRaw is an auto generated low-level Go binding around an Ethereum contract. -type IMessageRecipientRaw struct { - Contract *IMessageRecipient // Generic contract binding to access the raw methods on +// GlobalNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type GlobalNotaryRegistryRaw struct { + Contract *GlobalNotaryRegistry // Generic contract binding to access the raw methods on } -// IMessageRecipientCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type IMessageRecipientCallerRaw struct { - Contract *IMessageRecipientCaller // Generic read-only contract binding to access the raw methods on +// GlobalNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryCallerRaw struct { + Contract *GlobalNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on } -// IMessageRecipientTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type IMessageRecipientTransactorRaw struct { - Contract *IMessageRecipientTransactor // Generic write-only contract binding to access the raw methods on +// GlobalNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryTransactorRaw struct { + Contract *GlobalNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on } -// NewIMessageRecipient creates a new instance of IMessageRecipient, bound to a specific deployed contract. -func NewIMessageRecipient(address common.Address, backend bind.ContractBackend) (*IMessageRecipient, error) { - contract, err := bindIMessageRecipient(address, backend, backend, backend) +// NewGlobalNotaryRegistry creates a new instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistry(address common.Address, backend bind.ContractBackend) (*GlobalNotaryRegistry, error) { + contract, err := bindGlobalNotaryRegistry(address, backend, backend, backend) if err != nil { return nil, err } - return &IMessageRecipient{IMessageRecipientCaller: IMessageRecipientCaller{contract: contract}, IMessageRecipientTransactor: IMessageRecipientTransactor{contract: contract}, IMessageRecipientFilterer: IMessageRecipientFilterer{contract: contract}}, nil + return &GlobalNotaryRegistry{GlobalNotaryRegistryCaller: GlobalNotaryRegistryCaller{contract: contract}, GlobalNotaryRegistryTransactor: GlobalNotaryRegistryTransactor{contract: contract}, GlobalNotaryRegistryFilterer: GlobalNotaryRegistryFilterer{contract: contract}}, nil } -// NewIMessageRecipientCaller creates a new read-only instance of IMessageRecipient, bound to a specific deployed contract. -func NewIMessageRecipientCaller(address common.Address, caller bind.ContractCaller) (*IMessageRecipientCaller, error) { - contract, err := bindIMessageRecipient(address, caller, nil, nil) +// NewGlobalNotaryRegistryCaller creates a new read-only instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*GlobalNotaryRegistryCaller, error) { + contract, err := bindGlobalNotaryRegistry(address, caller, nil, nil) if err != nil { return nil, err } - return &IMessageRecipientCaller{contract: contract}, nil + return &GlobalNotaryRegistryCaller{contract: contract}, nil } -// NewIMessageRecipientTransactor creates a new write-only instance of IMessageRecipient, bound to a specific deployed contract. -func NewIMessageRecipientTransactor(address common.Address, transactor bind.ContractTransactor) (*IMessageRecipientTransactor, error) { - contract, err := bindIMessageRecipient(address, nil, transactor, nil) +// NewGlobalNotaryRegistryTransactor creates a new write-only instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*GlobalNotaryRegistryTransactor, error) { + contract, err := bindGlobalNotaryRegistry(address, nil, transactor, nil) if err != nil { return nil, err } - return &IMessageRecipientTransactor{contract: contract}, nil + return &GlobalNotaryRegistryTransactor{contract: contract}, nil } -// NewIMessageRecipientFilterer creates a new log filterer instance of IMessageRecipient, bound to a specific deployed contract. -func NewIMessageRecipientFilterer(address common.Address, filterer bind.ContractFilterer) (*IMessageRecipientFilterer, error) { - contract, err := bindIMessageRecipient(address, nil, nil, filterer) +// NewGlobalNotaryRegistryFilterer creates a new log filterer instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*GlobalNotaryRegistryFilterer, error) { + contract, err := bindGlobalNotaryRegistry(address, nil, nil, filterer) if err != nil { return nil, err } - return &IMessageRecipientFilterer{contract: contract}, nil + return &GlobalNotaryRegistryFilterer{contract: contract}, nil } -// bindIMessageRecipient binds a generic wrapper to an already deployed contract. -func bindIMessageRecipient(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(IMessageRecipientABI)) +// bindGlobalNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindGlobalNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(GlobalNotaryRegistryABI)) if err != nil { return nil, err } @@ -1453,175 +1619,468 @@ func bindIMessageRecipient(address common.Address, caller bind.ContractCaller, t // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_IMessageRecipient *IMessageRecipientRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IMessageRecipient.Contract.IMessageRecipientCaller.contract.Call(opts, result, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_IMessageRecipient *IMessageRecipientRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IMessageRecipient.Contract.IMessageRecipientTransactor.contract.Transfer(opts) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_IMessageRecipient *IMessageRecipientRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IMessageRecipient.Contract.IMessageRecipientTransactor.contract.Transact(opts, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_IMessageRecipient *IMessageRecipientCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IMessageRecipient.Contract.contract.Call(opts, result, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GlobalNotaryRegistry.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_IMessageRecipient *IMessageRecipientTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IMessageRecipient.Contract.contract.Transfer(opts) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_IMessageRecipient *IMessageRecipientTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IMessageRecipient.Contract.contract.Transact(opts, method, params...) -} - -// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. -// -// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() -func (_IMessageRecipient *IMessageRecipientTransactor) Handle(opts *bind.TransactOpts, _origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { - return _IMessageRecipient.contract.Transact(opts, "handle", _origin, _nonce, _sender, _rootTimestamp, _message) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.contract.Transact(opts, method, params...) } -// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. -// -// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() -func (_IMessageRecipient *IMessageRecipientSession) Handle(_origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { - return _IMessageRecipient.Contract.Handle(&_IMessageRecipient.TransactOpts, _origin, _nonce, _sender, _rootTimestamp, _message) -} +// GlobalNotaryRegistryNotaryAddedIterator is returned from FilterNotaryAdded and is used to iterate over the raw logs and unpacked data for NotaryAdded events raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryAddedIterator struct { + Event *GlobalNotaryRegistryNotaryAdded // Event containing the contract specifics and raw log -// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. -// -// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() -func (_IMessageRecipient *IMessageRecipientTransactorSession) Handle(_origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { - return _IMessageRecipient.Contract.Handle(&_IMessageRecipient.TransactOpts, _origin, _nonce, _sender, _rootTimestamp, _message) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// ISystemMessengerMetaData contains all meta data concerning the ISystemMessenger contract. -var ISystemMessengerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enumISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "0d1e27a7": "sendSystemMessage(uint32,uint8,bytes)", - }, + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// ISystemMessengerABI is the input ABI used to generate the binding from. -// Deprecated: Use ISystemMessengerMetaData.ABI instead. -var ISystemMessengerABI = ISystemMessengerMetaData.ABI +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GlobalNotaryRegistryNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GlobalNotaryRegistryNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Deprecated: Use ISystemMessengerMetaData.Sigs instead. -// ISystemMessengerFuncSigs maps the 4-byte function signature to its string representation. -var ISystemMessengerFuncSigs = ISystemMessengerMetaData.Sigs + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GlobalNotaryRegistryNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// ISystemMessenger is an auto generated Go binding around an Ethereum contract. -type ISystemMessenger struct { - ISystemMessengerCaller // Read-only binding to the contract - ISystemMessengerTransactor // Write-only binding to the contract - ISystemMessengerFilterer // Log filterer for contract events + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// ISystemMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. -type ISystemMessengerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GlobalNotaryRegistryNotaryAddedIterator) Error() error { + return it.fail } -// ISystemMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ISystemMessengerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GlobalNotaryRegistryNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// ISystemMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ISystemMessengerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GlobalNotaryRegistryNotaryAdded represents a NotaryAdded event raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryAdded struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// ISystemMessengerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ISystemMessengerSession struct { - Contract *ISystemMessenger // Generic contract binding to set the session for +// FilterNotaryAdded is a free log retrieval operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) FilterNotaryAdded(opts *bind.FilterOpts, domain []uint32) (*GlobalNotaryRegistryNotaryAddedIterator, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.FilterLogs(opts, "NotaryAdded", domainRule) + if err != nil { + return nil, err + } + return &GlobalNotaryRegistryNotaryAddedIterator{contract: _GlobalNotaryRegistry.contract, event: "NotaryAdded", logs: logs, sub: sub}, nil +} + +// WatchNotaryAdded is a free log subscription operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) WatchNotaryAdded(opts *bind.WatchOpts, sink chan<- *GlobalNotaryRegistryNotaryAdded, domain []uint32) (event.Subscription, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.WatchLogs(opts, "NotaryAdded", domainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GlobalNotaryRegistryNotaryAdded) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNotaryAdded is a log parse operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) ParseNotaryAdded(log types.Log) (*GlobalNotaryRegistryNotaryAdded, error) { + event := new(GlobalNotaryRegistryNotaryAdded) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GlobalNotaryRegistryNotaryRemovedIterator is returned from FilterNotaryRemoved and is used to iterate over the raw logs and unpacked data for NotaryRemoved events raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryRemovedIterator struct { + Event *GlobalNotaryRegistryNotaryRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GlobalNotaryRegistryNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GlobalNotaryRegistryNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GlobalNotaryRegistryNotaryRemoved represents a NotaryRemoved event raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryRemoved struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNotaryRemoved is a free log retrieval operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) FilterNotaryRemoved(opts *bind.FilterOpts, domain []uint32) (*GlobalNotaryRegistryNotaryRemovedIterator, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.FilterLogs(opts, "NotaryRemoved", domainRule) + if err != nil { + return nil, err + } + return &GlobalNotaryRegistryNotaryRemovedIterator{contract: _GlobalNotaryRegistry.contract, event: "NotaryRemoved", logs: logs, sub: sub}, nil +} + +// WatchNotaryRemoved is a free log subscription operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) WatchNotaryRemoved(opts *bind.WatchOpts, sink chan<- *GlobalNotaryRegistryNotaryRemoved, domain []uint32) (event.Subscription, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.WatchLogs(opts, "NotaryRemoved", domainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GlobalNotaryRegistryNotaryRemoved) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNotaryRemoved is a log parse operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) ParseNotaryRemoved(log types.Log) (*GlobalNotaryRegistryNotaryRemoved, error) { + event := new(GlobalNotaryRegistryNotaryRemoved) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardRegistryMetaData contains all meta data concerning the GuardRegistry contract. +var GuardRegistryMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "9fe03fa2": "allGuards()", + "629ddf69": "getGuard(uint256)", + "246c2449": "guardsAmount()", + }, + Bin: "0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220d8653df998fdaf3f226e0096ef80a5bc1cc7a5b0a57e68e9796a04188e80442064736f6c634300080d0033", +} + +// GuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use GuardRegistryMetaData.ABI instead. +var GuardRegistryABI = GuardRegistryMetaData.ABI + +// Deprecated: Use GuardRegistryMetaData.Sigs instead. +// GuardRegistryFuncSigs maps the 4-byte function signature to its string representation. +var GuardRegistryFuncSigs = GuardRegistryMetaData.Sigs + +// GuardRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GuardRegistryMetaData.Bin instead. +var GuardRegistryBin = GuardRegistryMetaData.Bin + +// DeployGuardRegistry deploys a new Ethereum contract, binding an instance of GuardRegistry to it. +func DeployGuardRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GuardRegistry, error) { + parsed, err := GuardRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GuardRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil +} + +// GuardRegistry is an auto generated Go binding around an Ethereum contract. +type GuardRegistry struct { + GuardRegistryCaller // Read-only binding to the contract + GuardRegistryTransactor // Write-only binding to the contract + GuardRegistryFilterer // Log filterer for contract events +} + +// GuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type GuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GuardRegistrySession struct { + Contract *GuardRegistry // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ISystemMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// GuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ISystemMessengerCallerSession struct { - Contract *ISystemMessengerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type GuardRegistryCallerSession struct { + Contract *GuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ISystemMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// GuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ISystemMessengerTransactorSession struct { - Contract *ISystemMessengerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type GuardRegistryTransactorSession struct { + Contract *GuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ISystemMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. -type ISystemMessengerRaw struct { - Contract *ISystemMessenger // Generic contract binding to access the raw methods on +// GuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type GuardRegistryRaw struct { + Contract *GuardRegistry // Generic contract binding to access the raw methods on } -// ISystemMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ISystemMessengerCallerRaw struct { - Contract *ISystemMessengerCaller // Generic read-only contract binding to access the raw methods on +// GuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GuardRegistryCallerRaw struct { + Contract *GuardRegistryCaller // Generic read-only contract binding to access the raw methods on } -// ISystemMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ISystemMessengerTransactorRaw struct { - Contract *ISystemMessengerTransactor // Generic write-only contract binding to access the raw methods on +// GuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GuardRegistryTransactorRaw struct { + Contract *GuardRegistryTransactor // Generic write-only contract binding to access the raw methods on } -// NewISystemMessenger creates a new instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessenger(address common.Address, backend bind.ContractBackend) (*ISystemMessenger, error) { - contract, err := bindISystemMessenger(address, backend, backend, backend) +// NewGuardRegistry creates a new instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistry(address common.Address, backend bind.ContractBackend) (*GuardRegistry, error) { + contract, err := bindGuardRegistry(address, backend, backend, backend) if err != nil { return nil, err } - return &ISystemMessenger{ISystemMessengerCaller: ISystemMessengerCaller{contract: contract}, ISystemMessengerTransactor: ISystemMessengerTransactor{contract: contract}, ISystemMessengerFilterer: ISystemMessengerFilterer{contract: contract}}, nil + return &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil } -// NewISystemMessengerCaller creates a new read-only instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerCaller(address common.Address, caller bind.ContractCaller) (*ISystemMessengerCaller, error) { - contract, err := bindISystemMessenger(address, caller, nil, nil) +// NewGuardRegistryCaller creates a new read-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*GuardRegistryCaller, error) { + contract, err := bindGuardRegistry(address, caller, nil, nil) if err != nil { return nil, err } - return &ISystemMessengerCaller{contract: contract}, nil + return &GuardRegistryCaller{contract: contract}, nil } -// NewISystemMessengerTransactor creates a new write-only instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*ISystemMessengerTransactor, error) { - contract, err := bindISystemMessenger(address, nil, transactor, nil) +// NewGuardRegistryTransactor creates a new write-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*GuardRegistryTransactor, error) { + contract, err := bindGuardRegistry(address, nil, transactor, nil) if err != nil { return nil, err } - return &ISystemMessengerTransactor{contract: contract}, nil + return &GuardRegistryTransactor{contract: contract}, nil } -// NewISystemMessengerFilterer creates a new log filterer instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*ISystemMessengerFilterer, error) { - contract, err := bindISystemMessenger(address, nil, nil, filterer) +// NewGuardRegistryFilterer creates a new log filterer instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*GuardRegistryFilterer, error) { + contract, err := bindGuardRegistry(address, nil, nil, filterer) if err != nil { return nil, err } - return &ISystemMessengerFilterer{contract: contract}, nil + return &GuardRegistryFilterer{contract: contract}, nil } -// bindISystemMessenger binds a generic wrapper to an already deployed contract. -func bindISystemMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ISystemMessengerABI)) +// bindGuardRegistry binds a generic wrapper to an already deployed contract. +func bindGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(GuardRegistryABI)) if err != nil { return nil, err } @@ -1632,215 +2091,270 @@ func bindISystemMessenger(address common.Address, caller bind.ContractCaller, tr // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ISystemMessenger *ISystemMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ISystemMessenger.Contract.ISystemMessengerCaller.contract.Call(opts, result, method, params...) +func (_GuardRegistry *GuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.GuardRegistryCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ISystemMessenger *ISystemMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transfer(opts) +func (_GuardRegistry *GuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ISystemMessenger *ISystemMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transact(opts, method, params...) +func (_GuardRegistry *GuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ISystemMessenger *ISystemMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ISystemMessenger.Contract.contract.Call(opts, result, method, params...) +func (_GuardRegistry *GuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ISystemMessenger.Contract.contract.Transfer(opts) +func (_GuardRegistry *GuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ISystemMessenger.Contract.contract.Transact(opts, method, params...) +func (_GuardRegistry *GuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transact(opts, method, params...) } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerTransactor) SendSystemMessage(opts *bind.TransactOpts, _destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.contract.Transact(opts, "sendSystemMessage", _destDomain, _recipient, _payload) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _GuardRegistry.contract.Call(opts, &out, "allGuards") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistrySession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerTransactorSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCallerSession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// InitializableMetaData contains all meta data concerning the Initializable contract. -var InitializableMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", -} +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _GuardRegistry.contract.Call(opts, &out, "getGuard", _index) -// InitializableABI is the input ABI used to generate the binding from. -// Deprecated: Use InitializableMetaData.ABI instead. -var InitializableABI = InitializableMetaData.ABI + if err != nil { + return *new(common.Address), err + } -// Initializable is an auto generated Go binding around an Ethereum contract. -type Initializable struct { - InitializableCaller // Read-only binding to the contract - InitializableTransactor // Write-only binding to the contract - InitializableFilterer // Log filterer for contract events -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) -// InitializableCaller is an auto generated read-only Go binding around an Ethereum contract. -type InitializableCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} + return out0, err -// InitializableTransactor is an auto generated write-only Go binding around an Ethereum contract. -type InitializableTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// InitializableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type InitializableFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistrySession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// InitializableSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type InitializableSession struct { - Contract *Initializable // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// InitializableCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type InitializableCallerSession struct { - Contract *InitializableCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _GuardRegistry.contract.Call(opts, &out, "guardsAmount") -// InitializableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type InitializableTransactorSession struct { - Contract *InitializableTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} + if err != nil { + return *new(*big.Int), err + } -// InitializableRaw is an auto generated low-level Go binding around an Ethereum contract. -type InitializableRaw struct { - Contract *Initializable // Generic contract binding to access the raw methods on -} + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err -// InitializableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type InitializableCallerRaw struct { - Contract *InitializableCaller // Generic read-only contract binding to access the raw methods on } -// InitializableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type InitializableTransactorRaw struct { - Contract *InitializableTransactor // Generic write-only contract binding to access the raw methods on +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistrySession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// NewInitializable creates a new instance of Initializable, bound to a specific deployed contract. -func NewInitializable(address common.Address, backend bind.ContractBackend) (*Initializable, error) { - contract, err := bindInitializable(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Initializable{InitializableCaller: InitializableCaller{contract: contract}, InitializableTransactor: InitializableTransactor{contract: contract}, InitializableFilterer: InitializableFilterer{contract: contract}}, nil +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCallerSession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// NewInitializableCaller creates a new read-only instance of Initializable, bound to a specific deployed contract. -func NewInitializableCaller(address common.Address, caller bind.ContractCaller) (*InitializableCaller, error) { - contract, err := bindInitializable(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &InitializableCaller{contract: contract}, nil +// GuardRegistryGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the GuardRegistry contract. +type GuardRegistryGuardAddedIterator struct { + Event *GuardRegistryGuardAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// NewInitializableTransactor creates a new write-only instance of Initializable, bound to a specific deployed contract. -func NewInitializableTransactor(address common.Address, transactor bind.ContractTransactor) (*InitializableTransactor, error) { - contract, err := bindInitializable(address, nil, transactor, nil) - if err != nil { - return nil, err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GuardRegistryGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } - return &InitializableTransactor{contract: contract}, nil -} + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// NewInitializableFilterer creates a new log filterer instance of Initializable, bound to a specific deployed contract. -func NewInitializableFilterer(address common.Address, filterer bind.ContractFilterer) (*InitializableFilterer, error) { - contract, err := bindInitializable(address, nil, nil, filterer) - if err != nil { - return nil, err + default: + return false + } } - return &InitializableFilterer{contract: contract}, nil -} + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// bindInitializable binds a generic wrapper to an already deployed contract. -func bindInitializable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(InitializableABI)) - if err != nil { - return nil, err + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Initializable *InitializableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Initializable.Contract.InitializableCaller.contract.Call(opts, result, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GuardRegistryGuardAddedIterator) Error() error { + return it.fail } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Initializable *InitializableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Initializable.Contract.InitializableTransactor.contract.Transfer(opts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardRegistryGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transact invokes the (paid) contract method with params as input values. -func (_Initializable *InitializableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Initializable.Contract.InitializableTransactor.contract.Transact(opts, method, params...) +// GuardRegistryGuardAdded represents a GuardAdded event raised by the GuardRegistry contract. +type GuardRegistryGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Initializable *InitializableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Initializable.Contract.contract.Call(opts, result, method, params...) +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*GuardRegistryGuardAddedIterator, error) { + + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return &GuardRegistryGuardAddedIterator{contract: _GuardRegistry.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Initializable *InitializableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Initializable.Contract.contract.Transfer(opts) +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardAdded) (event.Subscription, error) { + + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// Transact invokes the (paid) contract method with params as input values. -func (_Initializable *InitializableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Initializable.Contract.contract.Transact(opts, method, params...) +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardAdded(log types.Log) (*GuardRegistryGuardAdded, error) { + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// InitializableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Initializable contract. -type InitializableInitializedIterator struct { - Event *InitializableInitialized // Event containing the contract specifics and raw log +// GuardRegistryGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the GuardRegistry contract. +type GuardRegistryGuardRemovedIterator struct { + Event *GuardRegistryGuardRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1854,7 +2368,7 @@ type InitializableInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *InitializableInitializedIterator) Next() bool { +func (it *GuardRegistryGuardRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1863,7 +2377,7 @@ func (it *InitializableInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(InitializableInitialized) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1878,7 +2392,7 @@ func (it *InitializableInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(InitializableInitialized) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1894,41 +2408,41 @@ func (it *InitializableInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *InitializableInitializedIterator) Error() error { +func (it *GuardRegistryGuardRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *InitializableInitializedIterator) Close() error { +func (it *GuardRegistryGuardRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// InitializableInitialized represents a Initialized event raised by the Initializable contract. -type InitializableInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// GuardRegistryGuardRemoved represents a GuardRemoved event raised by the GuardRegistry contract. +type GuardRegistryGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) FilterInitialized(opts *bind.FilterOpts) (*InitializableInitializedIterator, error) { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*GuardRegistryGuardRemovedIterator, error) { - logs, sub, err := _Initializable.contract.FilterLogs(opts, "Initialized") + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardRemoved") if err != nil { return nil, err } - return &InitializableInitializedIterator{contract: _Initializable.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &GuardRegistryGuardRemovedIterator{contract: _GuardRegistry.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *InitializableInitialized) (event.Subscription, error) { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardRemoved) (event.Subscription, error) { - logs, sub, err := _Initializable.contract.WatchLogs(opts, "Initialized") + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardRemoved") if err != nil { return nil, err } @@ -1938,8 +2452,8 @@ func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOp select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(InitializableInitialized) - if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return err } event.Raw = log @@ -1960,35 +2474,35 @@ func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOp }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*InitializableInitialized, error) { - event := new(InitializableInitialized) - if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardRemoved(log types.Log) (*GuardRegistryGuardRemoved, error) { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// MerkleLibMetaData contains all meta data concerning the MerkleLib contract. -var MerkleLibMetaData = &bind.MetaData{ +// HeaderMetaData contains all meta data concerning the Header contract. +var HeaderMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208c25107868cbe1e9cbeeebef277d92e469db47e01c3a51a6f1455e28acab727464736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220327149decfae2d41d1bee270f572b99fa3be2335f1e9b1f315fbefbaf83be43264736f6c634300080d0033", } -// MerkleLibABI is the input ABI used to generate the binding from. -// Deprecated: Use MerkleLibMetaData.ABI instead. -var MerkleLibABI = MerkleLibMetaData.ABI +// HeaderABI is the input ABI used to generate the binding from. +// Deprecated: Use HeaderMetaData.ABI instead. +var HeaderABI = HeaderMetaData.ABI -// MerkleLibBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use MerkleLibMetaData.Bin instead. -var MerkleLibBin = MerkleLibMetaData.Bin +// HeaderBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HeaderMetaData.Bin instead. +var HeaderBin = HeaderMetaData.Bin -// DeployMerkleLib deploys a new Ethereum contract, binding an instance of MerkleLib to it. -func DeployMerkleLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MerkleLib, error) { - parsed, err := MerkleLibMetaData.GetAbi() +// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. +func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { + parsed, err := HeaderMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1996,111 +2510,111 @@ func DeployMerkleLib(auth *bind.TransactOpts, backend bind.ContractBackend) (com return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MerkleLibBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil + return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// MerkleLib is an auto generated Go binding around an Ethereum contract. -type MerkleLib struct { - MerkleLibCaller // Read-only binding to the contract - MerkleLibTransactor // Write-only binding to the contract - MerkleLibFilterer // Log filterer for contract events +// Header is an auto generated Go binding around an Ethereum contract. +type Header struct { + HeaderCaller // Read-only binding to the contract + HeaderTransactor // Write-only binding to the contract + HeaderFilterer // Log filterer for contract events } -// MerkleLibCaller is an auto generated read-only Go binding around an Ethereum contract. -type MerkleLibCaller struct { +// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. +type HeaderCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MerkleLibTransactor is an auto generated write-only Go binding around an Ethereum contract. -type MerkleLibTransactor struct { +// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HeaderTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MerkleLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type MerkleLibFilterer struct { +// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HeaderFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MerkleLibSession is an auto generated Go binding around an Ethereum contract, +// HeaderSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type MerkleLibSession struct { - Contract *MerkleLib // Generic contract binding to set the session for +type HeaderSession struct { + Contract *Header // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MerkleLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type MerkleLibCallerSession struct { - Contract *MerkleLibCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type HeaderCallerSession struct { + Contract *HeaderCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// MerkleLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type MerkleLibTransactorSession struct { - Contract *MerkleLibTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type HeaderTransactorSession struct { + Contract *HeaderTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MerkleLibRaw is an auto generated low-level Go binding around an Ethereum contract. -type MerkleLibRaw struct { - Contract *MerkleLib // Generic contract binding to access the raw methods on +// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. +type HeaderRaw struct { + Contract *Header // Generic contract binding to access the raw methods on } -// MerkleLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type MerkleLibCallerRaw struct { - Contract *MerkleLibCaller // Generic read-only contract binding to access the raw methods on +// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HeaderCallerRaw struct { + Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on } -// MerkleLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type MerkleLibTransactorRaw struct { - Contract *MerkleLibTransactor // Generic write-only contract binding to access the raw methods on +// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HeaderTransactorRaw struct { + Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on } -// NewMerkleLib creates a new instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLib(address common.Address, backend bind.ContractBackend) (*MerkleLib, error) { - contract, err := bindMerkleLib(address, backend, backend, backend) +// NewHeader creates a new instance of Header, bound to a specific deployed contract. +func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { + contract, err := bindHeader(address, backend, backend, backend) if err != nil { return nil, err } - return &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil + return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// NewMerkleLibCaller creates a new read-only instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibCaller(address common.Address, caller bind.ContractCaller) (*MerkleLibCaller, error) { - contract, err := bindMerkleLib(address, caller, nil, nil) +// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. +func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { + contract, err := bindHeader(address, caller, nil, nil) if err != nil { return nil, err } - return &MerkleLibCaller{contract: contract}, nil + return &HeaderCaller{contract: contract}, nil } -// NewMerkleLibTransactor creates a new write-only instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibTransactor(address common.Address, transactor bind.ContractTransactor) (*MerkleLibTransactor, error) { - contract, err := bindMerkleLib(address, nil, transactor, nil) +// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. +func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { + contract, err := bindHeader(address, nil, transactor, nil) if err != nil { return nil, err } - return &MerkleLibTransactor{contract: contract}, nil + return &HeaderTransactor{contract: contract}, nil } -// NewMerkleLibFilterer creates a new log filterer instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibFilterer(address common.Address, filterer bind.ContractFilterer) (*MerkleLibFilterer, error) { - contract, err := bindMerkleLib(address, nil, nil, filterer) +// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. +func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { + contract, err := bindHeader(address, nil, nil, filterer) if err != nil { return nil, err } - return &MerkleLibFilterer{contract: contract}, nil + return &HeaderFilterer{contract: contract}, nil } -// bindMerkleLib binds a generic wrapper to an already deployed contract. -func bindMerkleLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(MerkleLibABI)) +// bindHeader binds a generic wrapper to an already deployed contract. +func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HeaderABI)) if err != nil { return nil, err } @@ -2111,169 +2625,154 @@ func bindMerkleLib(address common.Address, caller bind.ContractCaller, transacto // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MerkleLib *MerkleLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MerkleLib.Contract.MerkleLibCaller.contract.Call(opts, result, method, params...) +func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_MerkleLib *MerkleLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MerkleLib.Contract.MerkleLibTransactor.contract.Transfer(opts) +func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_MerkleLib *MerkleLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MerkleLib.Contract.MerkleLibTransactor.contract.Transact(opts, method, params...) +func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MerkleLib *MerkleLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MerkleLib.Contract.contract.Call(opts, result, method, params...) +func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_MerkleLib *MerkleLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MerkleLib.Contract.contract.Transfer(opts) +func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_MerkleLib *MerkleLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MerkleLib.Contract.contract.Transact(opts, method, params...) +func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.contract.Transact(opts, method, params...) } -// MessageMetaData contains all meta data concerning the Message contract. -var MessageMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f424867ec96f6ba6ac980b7c42915bd0afc154d6ffcf0fdb0d83c6cf60b3c5a264736f6c634300080d0033", +// IMessageRecipientMetaData contains all meta data concerning the IMessageRecipient contract. +var IMessageRecipientMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_rootTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"handle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "e4d16d62": "handle(uint32,uint32,bytes32,uint256,bytes)", + }, } -// MessageABI is the input ABI used to generate the binding from. -// Deprecated: Use MessageMetaData.ABI instead. -var MessageABI = MessageMetaData.ABI - -// MessageBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use MessageMetaData.Bin instead. -var MessageBin = MessageMetaData.Bin - -// DeployMessage deploys a new Ethereum contract, binding an instance of Message to it. -func DeployMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Message, error) { - parsed, err := MessageMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// IMessageRecipientABI is the input ABI used to generate the binding from. +// Deprecated: Use IMessageRecipientMetaData.ABI instead. +var IMessageRecipientABI = IMessageRecipientMetaData.ABI - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MessageBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil -} +// Deprecated: Use IMessageRecipientMetaData.Sigs instead. +// IMessageRecipientFuncSigs maps the 4-byte function signature to its string representation. +var IMessageRecipientFuncSigs = IMessageRecipientMetaData.Sigs -// Message is an auto generated Go binding around an Ethereum contract. -type Message struct { - MessageCaller // Read-only binding to the contract - MessageTransactor // Write-only binding to the contract - MessageFilterer // Log filterer for contract events +// IMessageRecipient is an auto generated Go binding around an Ethereum contract. +type IMessageRecipient struct { + IMessageRecipientCaller // Read-only binding to the contract + IMessageRecipientTransactor // Write-only binding to the contract + IMessageRecipientFilterer // Log filterer for contract events } -// MessageCaller is an auto generated read-only Go binding around an Ethereum contract. -type MessageCaller struct { +// IMessageRecipientCaller is an auto generated read-only Go binding around an Ethereum contract. +type IMessageRecipientCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type MessageTransactor struct { +// IMessageRecipientTransactor is an auto generated write-only Go binding around an Ethereum contract. +type IMessageRecipientTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type MessageFilterer struct { +// IMessageRecipientFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IMessageRecipientFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageSession is an auto generated Go binding around an Ethereum contract, +// IMessageRecipientSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type MessageSession struct { - Contract *Message // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type IMessageRecipientSession struct { + Contract *IMessageRecipient // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// IMessageRecipientCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type MessageCallerSession struct { - Contract *MessageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type IMessageRecipientCallerSession struct { + Contract *IMessageRecipientCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// MessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// IMessageRecipientTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type MessageTransactorSession struct { - Contract *MessageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type IMessageRecipientTransactorSession struct { + Contract *IMessageRecipientTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MessageRaw is an auto generated low-level Go binding around an Ethereum contract. -type MessageRaw struct { - Contract *Message // Generic contract binding to access the raw methods on +// IMessageRecipientRaw is an auto generated low-level Go binding around an Ethereum contract. +type IMessageRecipientRaw struct { + Contract *IMessageRecipient // Generic contract binding to access the raw methods on } -// MessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type MessageCallerRaw struct { - Contract *MessageCaller // Generic read-only contract binding to access the raw methods on +// IMessageRecipientCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IMessageRecipientCallerRaw struct { + Contract *IMessageRecipientCaller // Generic read-only contract binding to access the raw methods on } -// MessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type MessageTransactorRaw struct { - Contract *MessageTransactor // Generic write-only contract binding to access the raw methods on +// IMessageRecipientTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IMessageRecipientTransactorRaw struct { + Contract *IMessageRecipientTransactor // Generic write-only contract binding to access the raw methods on } -// NewMessage creates a new instance of Message, bound to a specific deployed contract. -func NewMessage(address common.Address, backend bind.ContractBackend) (*Message, error) { - contract, err := bindMessage(address, backend, backend, backend) +// NewIMessageRecipient creates a new instance of IMessageRecipient, bound to a specific deployed contract. +func NewIMessageRecipient(address common.Address, backend bind.ContractBackend) (*IMessageRecipient, error) { + contract, err := bindIMessageRecipient(address, backend, backend, backend) if err != nil { return nil, err } - return &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil + return &IMessageRecipient{IMessageRecipientCaller: IMessageRecipientCaller{contract: contract}, IMessageRecipientTransactor: IMessageRecipientTransactor{contract: contract}, IMessageRecipientFilterer: IMessageRecipientFilterer{contract: contract}}, nil } -// NewMessageCaller creates a new read-only instance of Message, bound to a specific deployed contract. -func NewMessageCaller(address common.Address, caller bind.ContractCaller) (*MessageCaller, error) { - contract, err := bindMessage(address, caller, nil, nil) +// NewIMessageRecipientCaller creates a new read-only instance of IMessageRecipient, bound to a specific deployed contract. +func NewIMessageRecipientCaller(address common.Address, caller bind.ContractCaller) (*IMessageRecipientCaller, error) { + contract, err := bindIMessageRecipient(address, caller, nil, nil) if err != nil { return nil, err } - return &MessageCaller{contract: contract}, nil + return &IMessageRecipientCaller{contract: contract}, nil } -// NewMessageTransactor creates a new write-only instance of Message, bound to a specific deployed contract. -func NewMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*MessageTransactor, error) { - contract, err := bindMessage(address, nil, transactor, nil) +// NewIMessageRecipientTransactor creates a new write-only instance of IMessageRecipient, bound to a specific deployed contract. +func NewIMessageRecipientTransactor(address common.Address, transactor bind.ContractTransactor) (*IMessageRecipientTransactor, error) { + contract, err := bindIMessageRecipient(address, nil, transactor, nil) if err != nil { return nil, err } - return &MessageTransactor{contract: contract}, nil + return &IMessageRecipientTransactor{contract: contract}, nil } -// NewMessageFilterer creates a new log filterer instance of Message, bound to a specific deployed contract. -func NewMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*MessageFilterer, error) { - contract, err := bindMessage(address, nil, nil, filterer) +// NewIMessageRecipientFilterer creates a new log filterer instance of IMessageRecipient, bound to a specific deployed contract. +func NewIMessageRecipientFilterer(address common.Address, filterer bind.ContractFilterer) (*IMessageRecipientFilterer, error) { + contract, err := bindIMessageRecipient(address, nil, nil, filterer) if err != nil { return nil, err } - return &MessageFilterer{contract: contract}, nil + return &IMessageRecipientFilterer{contract: contract}, nil } -// bindMessage binds a generic wrapper to an already deployed contract. -func bindMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(MessageABI)) +// bindIMessageRecipient binds a generic wrapper to an already deployed contract. +func bindIMessageRecipient(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(IMessageRecipientABI)) if err != nil { return nil, err } @@ -2284,156 +2783,175 @@ func bindMessage(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Message *MessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Message.Contract.MessageCaller.contract.Call(opts, result, method, params...) +func (_IMessageRecipient *IMessageRecipientRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IMessageRecipient.Contract.IMessageRecipientCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Message *MessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Message.Contract.MessageTransactor.contract.Transfer(opts) +func (_IMessageRecipient *IMessageRecipientRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IMessageRecipient.Contract.IMessageRecipientTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Message *MessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Message.Contract.MessageTransactor.contract.Transact(opts, method, params...) +func (_IMessageRecipient *IMessageRecipientRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IMessageRecipient.Contract.IMessageRecipientTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Message *MessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Message.Contract.contract.Call(opts, result, method, params...) +func (_IMessageRecipient *IMessageRecipientCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IMessageRecipient.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Message *MessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Message.Contract.contract.Transfer(opts) +func (_IMessageRecipient *IMessageRecipientTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IMessageRecipient.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Message.Contract.contract.Transact(opts, method, params...) +func (_IMessageRecipient *IMessageRecipientTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IMessageRecipient.Contract.contract.Transact(opts, method, params...) } -// OwnableUpgradeableMetaData contains all meta data concerning the OwnableUpgradeable contract. -var OwnableUpgradeableMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. +// +// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() +func (_IMessageRecipient *IMessageRecipientTransactor) Handle(opts *bind.TransactOpts, _origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { + return _IMessageRecipient.contract.Transact(opts, "handle", _origin, _nonce, _sender, _rootTimestamp, _message) +} + +// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. +// +// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() +func (_IMessageRecipient *IMessageRecipientSession) Handle(_origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { + return _IMessageRecipient.Contract.Handle(&_IMessageRecipient.TransactOpts, _origin, _nonce, _sender, _rootTimestamp, _message) +} + +// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. +// +// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() +func (_IMessageRecipient *IMessageRecipientTransactorSession) Handle(_origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { + return _IMessageRecipient.Contract.Handle(&_IMessageRecipient.TransactOpts, _origin, _nonce, _sender, _rootTimestamp, _message) +} + +// ISystemMessengerMetaData contains all meta data concerning the ISystemMessenger contract. +var ISystemMessengerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enumISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Sigs: map[string]string{ - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "f2fde38b": "transferOwnership(address)", + "0d1e27a7": "sendSystemMessage(uint32,uint8,bytes)", }, } -// OwnableUpgradeableABI is the input ABI used to generate the binding from. -// Deprecated: Use OwnableUpgradeableMetaData.ABI instead. -var OwnableUpgradeableABI = OwnableUpgradeableMetaData.ABI +// ISystemMessengerABI is the input ABI used to generate the binding from. +// Deprecated: Use ISystemMessengerMetaData.ABI instead. +var ISystemMessengerABI = ISystemMessengerMetaData.ABI -// Deprecated: Use OwnableUpgradeableMetaData.Sigs instead. -// OwnableUpgradeableFuncSigs maps the 4-byte function signature to its string representation. -var OwnableUpgradeableFuncSigs = OwnableUpgradeableMetaData.Sigs +// Deprecated: Use ISystemMessengerMetaData.Sigs instead. +// ISystemMessengerFuncSigs maps the 4-byte function signature to its string representation. +var ISystemMessengerFuncSigs = ISystemMessengerMetaData.Sigs -// OwnableUpgradeable is an auto generated Go binding around an Ethereum contract. -type OwnableUpgradeable struct { - OwnableUpgradeableCaller // Read-only binding to the contract - OwnableUpgradeableTransactor // Write-only binding to the contract - OwnableUpgradeableFilterer // Log filterer for contract events +// ISystemMessenger is an auto generated Go binding around an Ethereum contract. +type ISystemMessenger struct { + ISystemMessengerCaller // Read-only binding to the contract + ISystemMessengerTransactor // Write-only binding to the contract + ISystemMessengerFilterer // Log filterer for contract events } -// OwnableUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. -type OwnableUpgradeableCaller struct { +// ISystemMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ISystemMessengerCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. -type OwnableUpgradeableTransactor struct { +// ISystemMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ISystemMessengerTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type OwnableUpgradeableFilterer struct { +// ISystemMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ISystemMessengerFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// ISystemMessengerSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type OwnableUpgradeableSession struct { - Contract *OwnableUpgradeable // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type ISystemMessengerSession struct { + Contract *ISystemMessenger // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// ISystemMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type OwnableUpgradeableCallerSession struct { - Contract *OwnableUpgradeableCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type ISystemMessengerCallerSession struct { + Contract *ISystemMessengerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// OwnableUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// ISystemMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type OwnableUpgradeableTransactorSession struct { - Contract *OwnableUpgradeableTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type ISystemMessengerTransactorSession struct { + Contract *ISystemMessengerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. -type OwnableUpgradeableRaw struct { - Contract *OwnableUpgradeable // Generic contract binding to access the raw methods on +// ISystemMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ISystemMessengerRaw struct { + Contract *ISystemMessenger // Generic contract binding to access the raw methods on } -// OwnableUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type OwnableUpgradeableCallerRaw struct { - Contract *OwnableUpgradeableCaller // Generic read-only contract binding to access the raw methods on +// ISystemMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ISystemMessengerCallerRaw struct { + Contract *ISystemMessengerCaller // Generic read-only contract binding to access the raw methods on } -// OwnableUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type OwnableUpgradeableTransactorRaw struct { - Contract *OwnableUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +// ISystemMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ISystemMessengerTransactorRaw struct { + Contract *ISystemMessengerTransactor // Generic write-only contract binding to access the raw methods on } -// NewOwnableUpgradeable creates a new instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeable(address common.Address, backend bind.ContractBackend) (*OwnableUpgradeable, error) { - contract, err := bindOwnableUpgradeable(address, backend, backend, backend) +// NewISystemMessenger creates a new instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessenger(address common.Address, backend bind.ContractBackend) (*ISystemMessenger, error) { + contract, err := bindISystemMessenger(address, backend, backend, backend) if err != nil { return nil, err } - return &OwnableUpgradeable{OwnableUpgradeableCaller: OwnableUpgradeableCaller{contract: contract}, OwnableUpgradeableTransactor: OwnableUpgradeableTransactor{contract: contract}, OwnableUpgradeableFilterer: OwnableUpgradeableFilterer{contract: contract}}, nil + return &ISystemMessenger{ISystemMessengerCaller: ISystemMessengerCaller{contract: contract}, ISystemMessengerTransactor: ISystemMessengerTransactor{contract: contract}, ISystemMessengerFilterer: ISystemMessengerFilterer{contract: contract}}, nil } -// NewOwnableUpgradeableCaller creates a new read-only instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*OwnableUpgradeableCaller, error) { - contract, err := bindOwnableUpgradeable(address, caller, nil, nil) +// NewISystemMessengerCaller creates a new read-only instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerCaller(address common.Address, caller bind.ContractCaller) (*ISystemMessengerCaller, error) { + contract, err := bindISystemMessenger(address, caller, nil, nil) if err != nil { return nil, err } - return &OwnableUpgradeableCaller{contract: contract}, nil + return &ISystemMessengerCaller{contract: contract}, nil } -// NewOwnableUpgradeableTransactor creates a new write-only instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableUpgradeableTransactor, error) { - contract, err := bindOwnableUpgradeable(address, nil, transactor, nil) +// NewISystemMessengerTransactor creates a new write-only instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*ISystemMessengerTransactor, error) { + contract, err := bindISystemMessenger(address, nil, transactor, nil) if err != nil { return nil, err } - return &OwnableUpgradeableTransactor{contract: contract}, nil + return &ISystemMessengerTransactor{contract: contract}, nil } -// NewOwnableUpgradeableFilterer creates a new log filterer instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableUpgradeableFilterer, error) { - contract, err := bindOwnableUpgradeable(address, nil, nil, filterer) +// NewISystemMessengerFilterer creates a new log filterer instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*ISystemMessengerFilterer, error) { + contract, err := bindISystemMessenger(address, nil, nil, filterer) if err != nil { return nil, err } - return &OwnableUpgradeableFilterer{contract: contract}, nil + return &ISystemMessengerFilterer{contract: contract}, nil } -// bindOwnableUpgradeable binds a generic wrapper to an already deployed contract. -func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(OwnableUpgradeableABI)) +// bindISystemMessenger binds a generic wrapper to an already deployed contract. +func bindISystemMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ISystemMessengerABI)) if err != nil { return nil, err } @@ -2444,116 +2962,215 @@ func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _OwnableUpgradeable.Contract.OwnableUpgradeableCaller.contract.Call(opts, result, method, params...) +func (_ISystemMessenger *ISystemMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ISystemMessenger.Contract.ISystemMessengerCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transfer(opts) +func (_ISystemMessenger *ISystemMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transact(opts, method, params...) +func (_ISystemMessenger *ISystemMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_OwnableUpgradeable *OwnableUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _OwnableUpgradeable.Contract.contract.Call(opts, result, method, params...) +func (_ISystemMessenger *ISystemMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ISystemMessenger.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.contract.Transfer(opts) +func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ISystemMessenger.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.contract.Transact(opts, method, params...) +func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ISystemMessenger.Contract.contract.Transact(opts, method, params...) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. // -// Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OwnableUpgradeable.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerTransactor) SendSystemMessage(opts *bind.TransactOpts, _destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.contract.Transact(opts, "sendSystemMessage", _destDomain, _recipient, _payload) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. // -// Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableSession) Owner() (common.Address, error) { - return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. // -// Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableCallerSession) Owner() (common.Address, error) { - return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) -} +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerTransactorSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) +} -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.contract.Transact(opts, "renounceOwnership") +// InitializableMetaData contains all meta data concerning the Initializable contract. +var InitializableMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) +// InitializableABI is the input ABI used to generate the binding from. +// Deprecated: Use InitializableMetaData.ABI instead. +var InitializableABI = InitializableMetaData.ABI + +// Initializable is an auto generated Go binding around an Ethereum contract. +type Initializable struct { + InitializableCaller // Read-only binding to the contract + InitializableTransactor // Write-only binding to the contract + InitializableFilterer // Log filterer for contract events } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) +// InitializableCaller is an auto generated read-only Go binding around an Ethereum contract. +type InitializableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) +// InitializableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type InitializableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +// InitializableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type InitializableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +// InitializableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type InitializableSession struct { + Contract *Initializable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the OwnableUpgradeable contract. -type OwnableUpgradeableInitializedIterator struct { - Event *OwnableUpgradeableInitialized // Event containing the contract specifics and raw log +// InitializableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type InitializableCallerSession struct { + Contract *InitializableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// InitializableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type InitializableTransactorSession struct { + Contract *InitializableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InitializableRaw is an auto generated low-level Go binding around an Ethereum contract. +type InitializableRaw struct { + Contract *Initializable // Generic contract binding to access the raw methods on +} + +// InitializableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type InitializableCallerRaw struct { + Contract *InitializableCaller // Generic read-only contract binding to access the raw methods on +} + +// InitializableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type InitializableTransactorRaw struct { + Contract *InitializableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewInitializable creates a new instance of Initializable, bound to a specific deployed contract. +func NewInitializable(address common.Address, backend bind.ContractBackend) (*Initializable, error) { + contract, err := bindInitializable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Initializable{InitializableCaller: InitializableCaller{contract: contract}, InitializableTransactor: InitializableTransactor{contract: contract}, InitializableFilterer: InitializableFilterer{contract: contract}}, nil +} + +// NewInitializableCaller creates a new read-only instance of Initializable, bound to a specific deployed contract. +func NewInitializableCaller(address common.Address, caller bind.ContractCaller) (*InitializableCaller, error) { + contract, err := bindInitializable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &InitializableCaller{contract: contract}, nil +} + +// NewInitializableTransactor creates a new write-only instance of Initializable, bound to a specific deployed contract. +func NewInitializableTransactor(address common.Address, transactor bind.ContractTransactor) (*InitializableTransactor, error) { + contract, err := bindInitializable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &InitializableTransactor{contract: contract}, nil +} + +// NewInitializableFilterer creates a new log filterer instance of Initializable, bound to a specific deployed contract. +func NewInitializableFilterer(address common.Address, filterer bind.ContractFilterer) (*InitializableFilterer, error) { + contract, err := bindInitializable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &InitializableFilterer{contract: contract}, nil +} + +// bindInitializable binds a generic wrapper to an already deployed contract. +func bindInitializable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(InitializableABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Initializable *InitializableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Initializable.Contract.InitializableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Initializable *InitializableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Initializable.Contract.InitializableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Initializable *InitializableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Initializable.Contract.InitializableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Initializable *InitializableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Initializable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Initializable *InitializableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Initializable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Initializable *InitializableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Initializable.Contract.contract.Transact(opts, method, params...) +} + +// InitializableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Initializable contract. +type InitializableInitializedIterator struct { + Event *InitializableInitialized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2567,7 +3184,7 @@ type OwnableUpgradeableInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *OwnableUpgradeableInitializedIterator) Next() bool { +func (it *InitializableInitializedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2576,7 +3193,7 @@ func (it *OwnableUpgradeableInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(OwnableUpgradeableInitialized) + it.Event = new(InitializableInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2591,7 +3208,7 @@ func (it *OwnableUpgradeableInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(OwnableUpgradeableInitialized) + it.Event = new(InitializableInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2607,19 +3224,19 @@ func (it *OwnableUpgradeableInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *OwnableUpgradeableInitializedIterator) Error() error { +func (it *InitializableInitializedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *OwnableUpgradeableInitializedIterator) Close() error { +func (it *InitializableInitializedIterator) Close() error { it.sub.Unsubscribe() return nil } -// OwnableUpgradeableInitialized represents a Initialized event raised by the OwnableUpgradeable contract. -type OwnableUpgradeableInitialized struct { +// InitializableInitialized represents a Initialized event raised by the Initializable contract. +type InitializableInitialized struct { Version uint8 Raw types.Log // Blockchain specific contextual infos } @@ -2627,21 +3244,21 @@ type OwnableUpgradeableInitialized struct { // FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // // Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*OwnableUpgradeableInitializedIterator, error) { +func (_Initializable *InitializableFilterer) FilterInitialized(opts *bind.FilterOpts) (*InitializableInitializedIterator, error) { - logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "Initialized") + logs, sub, err := _Initializable.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &OwnableUpgradeableInitializedIterator{contract: _OwnableUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &InitializableInitializedIterator{contract: _Initializable.contract, event: "Initialized", logs: logs, sub: sub}, nil } // WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // // Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableInitialized) (event.Subscription, error) { +func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *InitializableInitialized) (event.Subscription, error) { - logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "Initialized") + logs, sub, err := _Initializable.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } @@ -2651,8 +3268,8 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bi select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(OwnableUpgradeableInitialized) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(InitializableInitialized) + if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { return err } event.Raw = log @@ -2676,305 +3293,144 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bi // ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // // Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseInitialized(log types.Log) (*OwnableUpgradeableInitialized, error) { - event := new(OwnableUpgradeableInitialized) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { +func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*InitializableInitialized, error) { + event := new(InitializableInitialized) + if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } event.Raw = log return event, nil } -// OwnableUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the OwnableUpgradeable contract. -type OwnableUpgradeableOwnershipTransferredIterator struct { - Event *OwnableUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log +// MerkleLibMetaData contains all meta data concerning the MerkleLib contract. +var MerkleLibMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f9e4c7dc5d151b236f9264f903bb4cd1a70986338f4846708aa7937395914f8a64736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// MerkleLibABI is the input ABI used to generate the binding from. +// Deprecated: Use MerkleLibMetaData.ABI instead. +var MerkleLibABI = MerkleLibMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// MerkleLibBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MerkleLibMetaData.Bin instead. +var MerkleLibBin = MerkleLibMetaData.Bin -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(OwnableUpgradeableOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(OwnableUpgradeableOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// OwnableUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the OwnableUpgradeable contract. -type OwnableUpgradeableOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableUpgradeableOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &OwnableUpgradeableOwnershipTransferredIterator{contract: _OwnableUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(OwnableUpgradeableOwnershipTransferred) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableUpgradeableOwnershipTransferred, error) { - event := new(OwnableUpgradeableOwnershipTransferred) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ReplicaLibMetaData contains all meta data concerning the ReplicaLib contract. -var ReplicaLibMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"MESSAGE_STATUS_NONE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MESSAGE_STATUS_PROCESSED\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "b0075818": "MESSAGE_STATUS_NONE()", - "643d8086": "MESSAGE_STATUS_PROCESSED()", - }, - Bin: "0x6098610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea2646970667358221220b5521aa205eb54c917cf81b4f1c79b19818b68fef0fb5d39ccbdd943c15a444964736f6c634300080d0033", -} - -// ReplicaLibABI is the input ABI used to generate the binding from. -// Deprecated: Use ReplicaLibMetaData.ABI instead. -var ReplicaLibABI = ReplicaLibMetaData.ABI - -// Deprecated: Use ReplicaLibMetaData.Sigs instead. -// ReplicaLibFuncSigs maps the 4-byte function signature to its string representation. -var ReplicaLibFuncSigs = ReplicaLibMetaData.Sigs - -// ReplicaLibBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ReplicaLibMetaData.Bin instead. -var ReplicaLibBin = ReplicaLibMetaData.Bin - -// DeployReplicaLib deploys a new Ethereum contract, binding an instance of ReplicaLib to it. -func DeployReplicaLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ReplicaLib, error) { - parsed, err := ReplicaLibMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err +// DeployMerkleLib deploys a new Ethereum contract, binding an instance of MerkleLib to it. +func DeployMerkleLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MerkleLib, error) { + parsed, err := MerkleLibMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err } if parsed == nil { return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaLibBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MerkleLibBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ReplicaLib{ReplicaLibCaller: ReplicaLibCaller{contract: contract}, ReplicaLibTransactor: ReplicaLibTransactor{contract: contract}, ReplicaLibFilterer: ReplicaLibFilterer{contract: contract}}, nil + return address, tx, &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil } -// ReplicaLib is an auto generated Go binding around an Ethereum contract. -type ReplicaLib struct { - ReplicaLibCaller // Read-only binding to the contract - ReplicaLibTransactor // Write-only binding to the contract - ReplicaLibFilterer // Log filterer for contract events +// MerkleLib is an auto generated Go binding around an Ethereum contract. +type MerkleLib struct { + MerkleLibCaller // Read-only binding to the contract + MerkleLibTransactor // Write-only binding to the contract + MerkleLibFilterer // Log filterer for contract events } -// ReplicaLibCaller is an auto generated read-only Go binding around an Ethereum contract. -type ReplicaLibCaller struct { +// MerkleLibCaller is an auto generated read-only Go binding around an Ethereum contract. +type MerkleLibCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaLibTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ReplicaLibTransactor struct { +// MerkleLibTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MerkleLibTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ReplicaLibFilterer struct { +// MerkleLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MerkleLibFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaLibSession is an auto generated Go binding around an Ethereum contract, +// MerkleLibSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ReplicaLibSession struct { - Contract *ReplicaLib // Generic contract binding to set the session for +type MerkleLibSession struct { + Contract *MerkleLib // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ReplicaLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// MerkleLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ReplicaLibCallerSession struct { - Contract *ReplicaLibCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type MerkleLibCallerSession struct { + Contract *MerkleLibCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ReplicaLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// MerkleLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ReplicaLibTransactorSession struct { - Contract *ReplicaLibTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type MerkleLibTransactorSession struct { + Contract *MerkleLibTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ReplicaLibRaw is an auto generated low-level Go binding around an Ethereum contract. -type ReplicaLibRaw struct { - Contract *ReplicaLib // Generic contract binding to access the raw methods on +// MerkleLibRaw is an auto generated low-level Go binding around an Ethereum contract. +type MerkleLibRaw struct { + Contract *MerkleLib // Generic contract binding to access the raw methods on } -// ReplicaLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ReplicaLibCallerRaw struct { - Contract *ReplicaLibCaller // Generic read-only contract binding to access the raw methods on +// MerkleLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MerkleLibCallerRaw struct { + Contract *MerkleLibCaller // Generic read-only contract binding to access the raw methods on } -// ReplicaLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ReplicaLibTransactorRaw struct { - Contract *ReplicaLibTransactor // Generic write-only contract binding to access the raw methods on +// MerkleLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MerkleLibTransactorRaw struct { + Contract *MerkleLibTransactor // Generic write-only contract binding to access the raw methods on } -// NewReplicaLib creates a new instance of ReplicaLib, bound to a specific deployed contract. -func NewReplicaLib(address common.Address, backend bind.ContractBackend) (*ReplicaLib, error) { - contract, err := bindReplicaLib(address, backend, backend, backend) +// NewMerkleLib creates a new instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLib(address common.Address, backend bind.ContractBackend) (*MerkleLib, error) { + contract, err := bindMerkleLib(address, backend, backend, backend) if err != nil { return nil, err } - return &ReplicaLib{ReplicaLibCaller: ReplicaLibCaller{contract: contract}, ReplicaLibTransactor: ReplicaLibTransactor{contract: contract}, ReplicaLibFilterer: ReplicaLibFilterer{contract: contract}}, nil + return &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil } -// NewReplicaLibCaller creates a new read-only instance of ReplicaLib, bound to a specific deployed contract. -func NewReplicaLibCaller(address common.Address, caller bind.ContractCaller) (*ReplicaLibCaller, error) { - contract, err := bindReplicaLib(address, caller, nil, nil) +// NewMerkleLibCaller creates a new read-only instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibCaller(address common.Address, caller bind.ContractCaller) (*MerkleLibCaller, error) { + contract, err := bindMerkleLib(address, caller, nil, nil) if err != nil { return nil, err } - return &ReplicaLibCaller{contract: contract}, nil + return &MerkleLibCaller{contract: contract}, nil } -// NewReplicaLibTransactor creates a new write-only instance of ReplicaLib, bound to a specific deployed contract. -func NewReplicaLibTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaLibTransactor, error) { - contract, err := bindReplicaLib(address, nil, transactor, nil) +// NewMerkleLibTransactor creates a new write-only instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibTransactor(address common.Address, transactor bind.ContractTransactor) (*MerkleLibTransactor, error) { + contract, err := bindMerkleLib(address, nil, transactor, nil) if err != nil { return nil, err } - return &ReplicaLibTransactor{contract: contract}, nil + return &MerkleLibTransactor{contract: contract}, nil } -// NewReplicaLibFilterer creates a new log filterer instance of ReplicaLib, bound to a specific deployed contract. -func NewReplicaLibFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaLibFilterer, error) { - contract, err := bindReplicaLib(address, nil, nil, filterer) +// NewMerkleLibFilterer creates a new log filterer instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibFilterer(address common.Address, filterer bind.ContractFilterer) (*MerkleLibFilterer, error) { + contract, err := bindMerkleLib(address, nil, nil, filterer) if err != nil { return nil, err } - return &ReplicaLibFilterer{contract: contract}, nil + return &MerkleLibFilterer{contract: contract}, nil } -// bindReplicaLib binds a generic wrapper to an already deployed contract. -func bindReplicaLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ReplicaLibABI)) +// bindMerkleLib binds a generic wrapper to an already deployed contract. +func bindMerkleLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MerkleLibABI)) if err != nil { return nil, err } @@ -2985,144 +3441,57 @@ func bindReplicaLib(address common.Address, caller bind.ContractCaller, transact // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ReplicaLib *ReplicaLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaLib.Contract.ReplicaLibCaller.contract.Call(opts, result, method, params...) +func (_MerkleLib *MerkleLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MerkleLib.Contract.MerkleLibCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ReplicaLib *ReplicaLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaLib.Contract.ReplicaLibTransactor.contract.Transfer(opts) +func (_MerkleLib *MerkleLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MerkleLib.Contract.MerkleLibTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ReplicaLib *ReplicaLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaLib.Contract.ReplicaLibTransactor.contract.Transact(opts, method, params...) +func (_MerkleLib *MerkleLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MerkleLib.Contract.MerkleLibTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ReplicaLib *ReplicaLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaLib.Contract.contract.Call(opts, result, method, params...) +func (_MerkleLib *MerkleLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MerkleLib.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ReplicaLib *ReplicaLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaLib.Contract.contract.Transfer(opts) +func (_MerkleLib *MerkleLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MerkleLib.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ReplicaLib *ReplicaLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaLib.Contract.contract.Transact(opts, method, params...) -} - -// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. -// -// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) -func (_ReplicaLib *ReplicaLibCaller) MESSAGESTATUSNONE(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _ReplicaLib.contract.Call(opts, &out, "MESSAGE_STATUS_NONE") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. -// -// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) -func (_ReplicaLib *ReplicaLibSession) MESSAGESTATUSNONE() ([32]byte, error) { - return _ReplicaLib.Contract.MESSAGESTATUSNONE(&_ReplicaLib.CallOpts) -} - -// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. -// -// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) -func (_ReplicaLib *ReplicaLibCallerSession) MESSAGESTATUSNONE() ([32]byte, error) { - return _ReplicaLib.Contract.MESSAGESTATUSNONE(&_ReplicaLib.CallOpts) -} - -// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. -// -// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) -func (_ReplicaLib *ReplicaLibCaller) MESSAGESTATUSPROCESSED(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _ReplicaLib.contract.Call(opts, &out, "MESSAGE_STATUS_PROCESSED") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. -// -// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) -func (_ReplicaLib *ReplicaLibSession) MESSAGESTATUSPROCESSED() ([32]byte, error) { - return _ReplicaLib.Contract.MESSAGESTATUSPROCESSED(&_ReplicaLib.CallOpts) -} - -// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. -// -// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) -func (_ReplicaLib *ReplicaLibCallerSession) MESSAGESTATUSPROCESSED() ([32]byte, error) { - return _ReplicaLib.Contract.MESSAGESTATUSPROCESSED(&_ReplicaLib.CallOpts) +func (_MerkleLib *MerkleLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MerkleLib.Contract.contract.Transact(opts, method, params...) } -// ReplicaManagerMetaData contains all meta data concerning the ReplicaManager contract. -var ReplicaManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "ffa1ad74": "VERSION()", - "15a046aa": "acceptableRoot(uint32,uint32,bytes32)", - "7dfdba28": "activeReplicaConfirmedAt(uint32,bytes32)", - "63415514": "activeReplicaMessageStatus(uint32,bytes32)", - "b65672d3": "activeReplicaNonce(uint32)", - "8624c35c": "initialize(uint32,address)", - "8d3638f4": "localDomain()", - "8da5cb5b": "owner()", - "928bc4b2": "process(bytes)", - "4f63be3f": "prove(uint32,bytes,bytes32[32],uint256)", - "68705275": "proveAndProcess(uint32,bytes,bytes32[32],uint256)", - "715018a6": "renounceOwnership()", - "9df7d36d": "setConfirmation(uint32,bytes32,uint256)", - "b7bc563e": "setSystemMessenger(address)", - "9d54f419": "setUpdater(address)", - "f646a512": "submitAttestation(bytes)", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "df034cd0": "updater()", - }, - Bin: "0x60a06040523480156200001157600080fd5b5060405162002dbc38038062002dbc833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612d206200009c60003960008181610256015281816108470152610eb80152612d206000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c8063928bc4b2116100cd578063ccbdf9c911610081578063f2fde38b11610066578063f2fde38b1461038e578063f646a512146103a1578063ffa1ad74146103b457600080fd5b8063ccbdf9c91461034e578063df034cd01461036e57600080fd5b80639df7d36d116100b25780639df7d36d146102f2578063b65672d314610305578063b7bc563e1461033b57600080fd5b8063928bc4b2146102cc5780639d54f419146102df57600080fd5b8063715018a6116101245780638624c35c116101095780638624c35c1461023e5780638d3638f4146102515780638da5cb5b1461028d57600080fd5b8063715018a6146101f55780637dfdba28146101fd57600080fd5b806315a046aa146101565780634f63be3f1461017e578063634155141461019157806368705275146101e0575b600080fd5b610169610164366004612701565b6103ce565b60405190151581526020015b60405180910390f35b61016961018c366004612817565b61042b565b6101d261019f366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b604051908152602001610175565b6101f36101ee366004612817565b6105a5565b005b6101f361060c565b6101d261020b366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101f361024c3660046128d3565b610675565b6102787f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6101f36102da36600461290a565b6107ee565b6101f36102ed36600461293f565b610b8a565b6101f361030036600461295c565b610bfa565b61027861031336600461298f565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101f361034936600461293f565b610cee565b6066546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6101f361039c36600461293f565b610d9c565b6101f36103af36600461290a565b610e95565b6103bc600081565b60405160ff9091168152602001610175565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361040d576000915050610424565b61041d63ffffffff8516826129d9565b4210159150505b9392505050565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff16600281111561047a5761047a6129f1565b146104cc5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561052a5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016104c3565b60006105608387602080602002604051908101604052809291908260208002808284376000920191909152508991506110709050565b60008181526001840160205260409020549091501561059557600092835260029190910160205260409091205550600161059d565b600093505050505b949350505050565b6105b18484848461042b565b6105fd5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016104c3565b610606836107ee565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106735760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b565b60006106816001611116565b905080156106b657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6106bf8261126d565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107708360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc602052604090205580156107e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006107f9826112f2565b9050600061080c62ffffff198316611306565b9050600061081f62ffffff198316611346565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661087662ffffff198516611370565b63ffffffff16146108c95760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016104c3565b60006108da62ffffff198616611391565b60008181526002840160205260409020549091506108f7816113ee565b6109435760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016104c3565b61095c8461095662ffffff198816611402565b836103ce565b6109a85760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016104c3565b60c95460ff166001146109fd5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016104c3565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610a3a610a3762ffffff198816611423565b50565b6000828152600284016020526040812060019055610a65610a6062ffffff19881661145a565b61147b565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610a9362ffffff198a166114bd565b610aa262ffffff198b166114de565b600087815260018a016020526040902054610ad0610ac562ffffff198f166114ff565b62ffffff191661153e565b6040518663ffffffff1660e01b8152600401610af0959493929190612a8b565b600060405180830381600087803b158015610b0a57600080fd5b505af1158015610b1e573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bf15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b610a3781611591565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610ca49083908690869061161716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d555760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b73ffffffffffffffffffffffffffffffffffffffff8116610e8c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104c3565b610a378161162b565b6000610ea0826116a2565b9150506000610eb48262ffffff19166117c3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610f315760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016104c3565b6000610f4262ffffff1984166117d7565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020805492935091811690831611610fbd5760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016104c3565b6000610fce62ffffff1986166117eb565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171611053610ac58a62ffffff1916611800565b6040516110609190612acb565b60405180910390a4505050505050565b8260005b602081101561110e57600183821c16600085836020811061109757611097612ade565b60200201519050816001036110d7576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611104565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611074565b509392505050565b60008054610100900460ff16156111b3578160ff1660011480156111395750303b155b6111ab5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b506000919050565b60005460ff8084169116106112305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166112ea5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610bf1611833565b6000611300826105396118b8565b92915050565b60008161131b62ffffff1982166105396118dc565b5061133d8361132b8560016119dd565b6113368660026119dd565b6001611a0f565b91505b50919050565b60008161135c60015b62ffffff198316906118dc565b5061133d62ffffff19841660026004611a2e565b60008161137d600161134f565b5061133d62ffffff198416602a6004611a2e565b6000806113ac8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006113d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906113005750506001141590565b60008161140f600161134f565b5061133d62ffffff198416604e6004611a2e565b60008161143862ffffff1982166105396118dc565b5061133d836114488560026119dd565b6114538660036119dd565b6002611a0f565b600081611467600161134f565b5061133d62ffffff198416602e6020611a5e565b60007401000000000000000000000000000000000000000082016114b757505060665473ffffffffffffffffffffffffffffffffffffffff1690565b81611300565b6000816114ca600161134f565b5061133d62ffffff19841660266004611a2e565b6000816114eb600161134f565b5061133d62ffffff19841660066020611a5e565b60008161151462ffffff1982166105396118dc565b5061133d836115248560036119dd565b601886901c6bffffffffffffffffffffffff166003611a0f565b606060008061155b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506115808483602001611c1c565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806116af83826118b8565b905060286bffffffffffffffffffffffff601883901c16116117135760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016104c3565b61173c61172562ffffff198316611dc1565b611737610ac562ffffff198516611800565b611dd6565b915061177261175062ffffff1983166117c3565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6117be5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e2075706461746572000000000000000060448201526064016104c3565b915091565b600061130062ffffff198316826004611a2e565b600061130062ffffff198316600480611a2e565b600061130062ffffff19831660086020611a5e565b6000611300602861182381601886901c6bffffffffffffffffffffffff16612b0d565b62ffffff19851691906000611e4d565b600054610100900460ff166118b05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610673611ec7565b8151600090602084016118d364ffffffffff85168284611f4d565b95945050505050565b60006118e88383611f94565b6119d65760006119076118fb8560d81c90565b64ffffffffff16611fb7565b915050600061191c8464ffffffffff16611fb7565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016104c39190612acb565b5090919050565b600061042460028360048111156119f6576119f66129f1565b611a009190612b24565b62ffffff198516906002611a2e565b60006118d384611a1f8186612b0d565b62ffffff198816919085611e4d565b6000611a3b826020612b61565b611a46906008612b84565b60ff16611a54858585611a5e565b901c949350505050565b60008160ff16600003611a7357506000610424565b611a8b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aa660ff8416856129d9565b1115611b1e57611b05611ac78560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aed8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166120a1565b60405162461bcd60e51b81526004016104c39190612acb565b60208260ff161115611b985760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104c3565b600882026000611bb68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611c995760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016104c3565b611ca28361210f565b611d145760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016104c3565b6000611d2e8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611d588560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611d7d5760206060fd5b8285848460045afa50611db7611d938760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061130062ffffff19831682602881611e4d565b600080611de862ffffff198516611391565b9050611e41816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061059d818461214c565b600080611e688660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050611e8186612168565b84611e8c87846129d9565b611e9691906129d9565b1115611ea95762ffffff1991505061059d565b611eb385826129d9565b9050611db78364ffffffffff168286611f4d565b600054610100900460ff16611f445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b6106733361162b565b600080611f5a83856129d9565b9050604051811115611f6a575060005b80600003611f7f5762ffffff19915050610424565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16611fa88460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561202a576000611fd6826008612b84565b60ff1685901c9050611fe7816121b0565b61ffff16841793508160ff1660101461200257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611fbd565b50600f5b60ff8160ff16101561209b576000612047826008612b84565b60ff1685901c9050612058816121b0565b61ffff16831792508160ff1660001461207357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161202e565b50915091565b606060006120ae86611fb7565b91505060006120bc86611fb7565b91505060006120ca86611fb7565b91505060006120d886611fb7565b915050838383836040516020016120f29493929190612bad565b604051602081830303815290604052945050505050949350505050565b600061211b8260d81c90565b64ffffffffff1664ffffffffff0361213557506000919050565b600061214083612168565b60405110199392505050565b600080600061215b85856121e2565b9150915061110e81612250565b60006121828260181c6bffffffffffffffffffffffff1690565b61219a8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006121c260048360ff16901c61243c565b60ff1661ffff919091161760081b6121d98261243c565b60ff1617919050565b60008082516041036122185760208301516040840151606085015160001a61220c87828585612583565b94509450505050612249565b8251604003612241576020830151604084015161223686838361269b565b935093505050612249565b506000905060025b9250929050565b6000816004811115612264576122646129f1565b0361226c5750565b6001816004811115612280576122806129f1565b036122cd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104c3565b60028160048111156122e1576122e16129f1565b0361232e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104c3565b6003816004811115612342576123426129f1565b036123b55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b60048160048111156123c9576123c96129f1565b03610a375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b600060f08083179060ff821690036124575750603092915050565b8060ff1660f10361246b5750603192915050565b8060ff1660f20361247f5750603292915050565b8060ff1660f3036124935750603392915050565b8060ff1660f4036124a75750603492915050565b8060ff1660f5036124bb5750603592915050565b8060ff1660f6036124cf5750603692915050565b8060ff1660f7036124e35750603792915050565b8060ff1660f8036124f75750603892915050565b8060ff1660f90361250b5750603992915050565b8060ff1660fa0361251f5750606192915050565b8060ff1660fb036125335750606292915050565b8060ff1660fc036125475750606392915050565b8060ff1660fd0361255b5750606492915050565b8060ff1660fe0361256f5750606592915050565b8060ff1660ff036113405750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156125ba5750600090506003612692565b8460ff16601b141580156125d257508460ff16601c14155b156125e35750600090506004612692565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612637573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661268b57600060019250925050612692565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816126d160ff86901c601b6129d9565b90506126df87828885612583565b935093505050935093915050565b803563ffffffff8116811461126857600080fd5b60008060006060848603121561271657600080fd5b61271f846126ed565b925061272d602085016126ed565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261277d57600080fd5b813567ffffffffffffffff808211156127985761279861273d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156127de576127de61273d565b816040528381528660208588010111156127f757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561282e57600080fd5b612837856126ed565b9350602085013567ffffffffffffffff81111561285357600080fd5b61285f8782880161276c565b93505061044085018681111561287457600080fd5b9396929550505060409290920191903590565b6000806040838503121561289a57600080fd5b6128a3836126ed565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a3757600080fd5b600080604083850312156128e657600080fd5b6128ef836126ed565b915060208301356128ff816128b1565b809150509250929050565b60006020828403121561291c57600080fd5b813567ffffffffffffffff81111561293357600080fd5b61059d8482850161276c565b60006020828403121561295157600080fd5b8135610424816128b1565b60008060006060848603121561297157600080fd5b61297a846126ed565b95602085013595506040909401359392505050565b6000602082840312156129a157600080fd5b610424826126ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156129ec576129ec6129aa565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612a4657602081850181015186830182015201612a2a565b81811115612a58576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612ac060a0830184612a20565b979650505050505050565b6020815260006104246020830184612a20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612b1f57612b1f6129aa565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b5c57612b5c6129aa565b500290565b600060ff821660ff841680821015612b7b57612b7b6129aa565b90039392505050565b600060ff821660ff84168160ff0481118215151615612ba557612ba56129aa565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611db756fea2646970667358221220c2d6abd028a1cb35e1537efe976dc2970cbb4dbe911ca61808e63125c173e4c964736f6c634300080d0033", +// MessageMetaData contains all meta data concerning the Message contract. +var MessageMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122079c2aafd2e40ca3223c5407baca610ee6e69860782d73244303ca51c7c6debc164736f6c634300080d0033", } -// ReplicaManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use ReplicaManagerMetaData.ABI instead. -var ReplicaManagerABI = ReplicaManagerMetaData.ABI - -// Deprecated: Use ReplicaManagerMetaData.Sigs instead. -// ReplicaManagerFuncSigs maps the 4-byte function signature to its string representation. -var ReplicaManagerFuncSigs = ReplicaManagerMetaData.Sigs +// MessageABI is the input ABI used to generate the binding from. +// Deprecated: Use MessageMetaData.ABI instead. +var MessageABI = MessageMetaData.ABI -// ReplicaManagerBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ReplicaManagerMetaData.Bin instead. -var ReplicaManagerBin = ReplicaManagerMetaData.Bin +// MessageBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MessageMetaData.Bin instead. +var MessageBin = MessageMetaData.Bin -// DeployReplicaManager deploys a new Ethereum contract, binding an instance of ReplicaManager to it. -func DeployReplicaManager(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *ReplicaManager, error) { - parsed, err := ReplicaManagerMetaData.GetAbi() +// DeployMessage deploys a new Ethereum contract, binding an instance of Message to it. +func DeployMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Message, error) { + parsed, err := MessageMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -3130,111 +3499,111 @@ func DeployReplicaManager(auth *bind.TransactOpts, backend bind.ContractBackend, return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaManagerBin), backend, _localDomain) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MessageBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ReplicaManager{ReplicaManagerCaller: ReplicaManagerCaller{contract: contract}, ReplicaManagerTransactor: ReplicaManagerTransactor{contract: contract}, ReplicaManagerFilterer: ReplicaManagerFilterer{contract: contract}}, nil + return address, tx, &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil } -// ReplicaManager is an auto generated Go binding around an Ethereum contract. -type ReplicaManager struct { - ReplicaManagerCaller // Read-only binding to the contract - ReplicaManagerTransactor // Write-only binding to the contract - ReplicaManagerFilterer // Log filterer for contract events +// Message is an auto generated Go binding around an Ethereum contract. +type Message struct { + MessageCaller // Read-only binding to the contract + MessageTransactor // Write-only binding to the contract + MessageFilterer // Log filterer for contract events } -// ReplicaManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type ReplicaManagerCaller struct { +// MessageCaller is an auto generated read-only Go binding around an Ethereum contract. +type MessageCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ReplicaManagerTransactor struct { +// MessageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MessageTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ReplicaManagerFilterer struct { +// MessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MessageFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaManagerSession is an auto generated Go binding around an Ethereum contract, +// MessageSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ReplicaManagerSession struct { - Contract *ReplicaManager // Generic contract binding to set the session for +type MessageSession struct { + Contract *Message // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ReplicaManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// MessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ReplicaManagerCallerSession struct { - Contract *ReplicaManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type MessageCallerSession struct { + Contract *MessageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ReplicaManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// MessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ReplicaManagerTransactorSession struct { - Contract *ReplicaManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type MessageTransactorSession struct { + Contract *MessageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ReplicaManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type ReplicaManagerRaw struct { - Contract *ReplicaManager // Generic contract binding to access the raw methods on +// MessageRaw is an auto generated low-level Go binding around an Ethereum contract. +type MessageRaw struct { + Contract *Message // Generic contract binding to access the raw methods on } -// ReplicaManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ReplicaManagerCallerRaw struct { - Contract *ReplicaManagerCaller // Generic read-only contract binding to access the raw methods on +// MessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MessageCallerRaw struct { + Contract *MessageCaller // Generic read-only contract binding to access the raw methods on } -// ReplicaManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ReplicaManagerTransactorRaw struct { - Contract *ReplicaManagerTransactor // Generic write-only contract binding to access the raw methods on +// MessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MessageTransactorRaw struct { + Contract *MessageTransactor // Generic write-only contract binding to access the raw methods on } -// NewReplicaManager creates a new instance of ReplicaManager, bound to a specific deployed contract. -func NewReplicaManager(address common.Address, backend bind.ContractBackend) (*ReplicaManager, error) { - contract, err := bindReplicaManager(address, backend, backend, backend) +// NewMessage creates a new instance of Message, bound to a specific deployed contract. +func NewMessage(address common.Address, backend bind.ContractBackend) (*Message, error) { + contract, err := bindMessage(address, backend, backend, backend) if err != nil { return nil, err } - return &ReplicaManager{ReplicaManagerCaller: ReplicaManagerCaller{contract: contract}, ReplicaManagerTransactor: ReplicaManagerTransactor{contract: contract}, ReplicaManagerFilterer: ReplicaManagerFilterer{contract: contract}}, nil + return &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil } -// NewReplicaManagerCaller creates a new read-only instance of ReplicaManager, bound to a specific deployed contract. -func NewReplicaManagerCaller(address common.Address, caller bind.ContractCaller) (*ReplicaManagerCaller, error) { - contract, err := bindReplicaManager(address, caller, nil, nil) +// NewMessageCaller creates a new read-only instance of Message, bound to a specific deployed contract. +func NewMessageCaller(address common.Address, caller bind.ContractCaller) (*MessageCaller, error) { + contract, err := bindMessage(address, caller, nil, nil) if err != nil { return nil, err } - return &ReplicaManagerCaller{contract: contract}, nil + return &MessageCaller{contract: contract}, nil } -// NewReplicaManagerTransactor creates a new write-only instance of ReplicaManager, bound to a specific deployed contract. -func NewReplicaManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaManagerTransactor, error) { - contract, err := bindReplicaManager(address, nil, transactor, nil) +// NewMessageTransactor creates a new write-only instance of Message, bound to a specific deployed contract. +func NewMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*MessageTransactor, error) { + contract, err := bindMessage(address, nil, transactor, nil) if err != nil { return nil, err } - return &ReplicaManagerTransactor{contract: contract}, nil + return &MessageTransactor{contract: contract}, nil } -// NewReplicaManagerFilterer creates a new log filterer instance of ReplicaManager, bound to a specific deployed contract. -func NewReplicaManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaManagerFilterer, error) { - contract, err := bindReplicaManager(address, nil, nil, filterer) +// NewMessageFilterer creates a new log filterer instance of Message, bound to a specific deployed contract. +func NewMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*MessageFilterer, error) { + contract, err := bindMessage(address, nil, nil, filterer) if err != nil { return nil, err } - return &ReplicaManagerFilterer{contract: contract}, nil + return &MessageFilterer{contract: contract}, nil } -// bindReplicaManager binds a generic wrapper to an already deployed contract. -func bindReplicaManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ReplicaManagerABI)) +// bindMessage binds a generic wrapper to an already deployed contract. +func bindMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MessageABI)) if err != nil { return nil, err } @@ -3245,535 +3614,413 @@ func bindReplicaManager(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ReplicaManager *ReplicaManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaManager.Contract.ReplicaManagerCaller.contract.Call(opts, result, method, params...) +func (_Message *MessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Message.Contract.MessageCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ReplicaManager *ReplicaManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManager.Contract.ReplicaManagerTransactor.contract.Transfer(opts) +func (_Message *MessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Message.Contract.MessageTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ReplicaManager *ReplicaManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaManager.Contract.ReplicaManagerTransactor.contract.Transact(opts, method, params...) +func (_Message *MessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Message.Contract.MessageTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ReplicaManager *ReplicaManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaManager.Contract.contract.Call(opts, result, method, params...) +func (_Message *MessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Message.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ReplicaManager *ReplicaManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManager.Contract.contract.Transfer(opts) +func (_Message *MessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Message.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ReplicaManager *ReplicaManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaManager.Contract.contract.Transact(opts, method, params...) +func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Message.Contract.contract.Transact(opts, method, params...) } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManager *ReplicaManagerCaller) VERSION(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "VERSION") - - if err != nil { - return *new(uint8), err - } +// OwnableUpgradeableMetaData contains all meta data concerning the OwnableUpgradeable contract. +var OwnableUpgradeableMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "f2fde38b": "transferOwnership(address)", + }, +} - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) +// OwnableUpgradeableABI is the input ABI used to generate the binding from. +// Deprecated: Use OwnableUpgradeableMetaData.ABI instead. +var OwnableUpgradeableABI = OwnableUpgradeableMetaData.ABI - return out0, err +// Deprecated: Use OwnableUpgradeableMetaData.Sigs instead. +// OwnableUpgradeableFuncSigs maps the 4-byte function signature to its string representation. +var OwnableUpgradeableFuncSigs = OwnableUpgradeableMetaData.Sigs +// OwnableUpgradeable is an auto generated Go binding around an Ethereum contract. +type OwnableUpgradeable struct { + OwnableUpgradeableCaller // Read-only binding to the contract + OwnableUpgradeableTransactor // Write-only binding to the contract + OwnableUpgradeableFilterer // Log filterer for contract events } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManager *ReplicaManagerSession) VERSION() (uint8, error) { - return _ReplicaManager.Contract.VERSION(&_ReplicaManager.CallOpts) +// OwnableUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. +type OwnableUpgradeableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManager *ReplicaManagerCallerSession) VERSION() (uint8, error) { - return _ReplicaManager.Contract.VERSION(&_ReplicaManager.CallOpts) +// OwnableUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type OwnableUpgradeableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. -// -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManager *ReplicaManagerCaller) AcceptableRoot(opts *bind.CallOpts, _remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "acceptableRoot", _remoteDomain, _optimisticSeconds, _root) - - if err != nil { - return *new(bool), err - } +// OwnableUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OwnableUpgradeableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) +// OwnableUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type OwnableUpgradeableSession struct { + Contract *OwnableUpgradeable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - return out0, err +// OwnableUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type OwnableUpgradeableCallerSession struct { + Contract *OwnableUpgradeableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} +// OwnableUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type OwnableUpgradeableTransactorSession struct { + Contract *OwnableUpgradeableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. -// -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManager *ReplicaManagerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { - return _ReplicaManager.Contract.AcceptableRoot(&_ReplicaManager.CallOpts, _remoteDomain, _optimisticSeconds, _root) +// OwnableUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. +type OwnableUpgradeableRaw struct { + Contract *OwnableUpgradeable // Generic contract binding to access the raw methods on } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. -// -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManager *ReplicaManagerCallerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { - return _ReplicaManager.Contract.AcceptableRoot(&_ReplicaManager.CallOpts, _remoteDomain, _optimisticSeconds, _root) +// OwnableUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OwnableUpgradeableCallerRaw struct { + Contract *OwnableUpgradeableCaller // Generic read-only contract binding to access the raw methods on } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. -// -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaConfirmedAt(opts *bind.CallOpts, _remoteDomain uint32, _root [32]byte) (*big.Int, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaConfirmedAt", _remoteDomain, _root) +// OwnableUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OwnableUpgradeableTransactorRaw struct { + Contract *OwnableUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +} +// NewOwnableUpgradeable creates a new instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeable(address common.Address, backend bind.ContractBackend) (*OwnableUpgradeable, error) { + contract, err := bindOwnableUpgradeable(address, backend, backend, backend) if err != nil { - return *new(*big.Int), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - + return &OwnableUpgradeable{OwnableUpgradeableCaller: OwnableUpgradeableCaller{contract: contract}, OwnableUpgradeableTransactor: OwnableUpgradeableTransactor{contract: contract}, OwnableUpgradeableFilterer: OwnableUpgradeableFilterer{contract: contract}}, nil } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. -// -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { - return _ReplicaManager.Contract.ActiveReplicaConfirmedAt(&_ReplicaManager.CallOpts, _remoteDomain, _root) +// NewOwnableUpgradeableCaller creates a new read-only instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*OwnableUpgradeableCaller, error) { + contract, err := bindOwnableUpgradeable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OwnableUpgradeableCaller{contract: contract}, nil } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. -// -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { - return _ReplicaManager.Contract.ActiveReplicaConfirmedAt(&_ReplicaManager.CallOpts, _remoteDomain, _root) +// NewOwnableUpgradeableTransactor creates a new write-only instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableUpgradeableTransactor, error) { + contract, err := bindOwnableUpgradeable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OwnableUpgradeableTransactor{contract: contract}, nil } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. -// -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaMessageStatus(opts *bind.CallOpts, _remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaMessageStatus", _remoteDomain, _messageId) - +// NewOwnableUpgradeableFilterer creates a new log filterer instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableUpgradeableFilterer, error) { + contract, err := bindOwnableUpgradeable(address, nil, nil, filterer) if err != nil { - return *new([32]byte), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - + return &OwnableUpgradeableFilterer{contract: contract}, nil } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. -// -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - return _ReplicaManager.Contract.ActiveReplicaMessageStatus(&_ReplicaManager.CallOpts, _remoteDomain, _messageId) +// bindOwnableUpgradeable binds a generic wrapper to an already deployed contract. +func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(OwnableUpgradeableABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. -// -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - return _ReplicaManager.Contract.ActiveReplicaMessageStatus(&_ReplicaManager.CallOpts, _remoteDomain, _messageId) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OwnableUpgradeable.Contract.OwnableUpgradeableCaller.contract.Call(opts, result, method, params...) } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. -// -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaNonce(opts *bind.CallOpts, _remoteDomain uint32) (uint32, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaNonce", _remoteDomain) - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transfer(opts) +} - return out0, err +// Transact invokes the (paid) contract method with params as input values. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transact(opts, method, params...) +} +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OwnableUpgradeable *OwnableUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OwnableUpgradeable.Contract.contract.Call(opts, result, method, params...) } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. -// -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { - return _ReplicaManager.Contract.ActiveReplicaNonce(&_ReplicaManager.CallOpts, _remoteDomain) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.contract.Transfer(opts) } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. -// -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { - return _ReplicaManager.Contract.ActiveReplicaNonce(&_ReplicaManager.CallOpts, _remoteDomain) +// Transact invokes the (paid) contract method with params as input values. +func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.contract.Transact(opts, method, params...) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManager *ReplicaManagerCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "localDomain") + err := _OwnableUpgradeable.contract.Call(opts, &out, "owner") if err != nil { - return *new(uint32), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManager *ReplicaManagerSession) LocalDomain() (uint32, error) { - return _ReplicaManager.Contract.LocalDomain(&_ReplicaManager.CallOpts) -} - -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManager *ReplicaManagerCallerSession) LocalDomain() (uint32, error) { - return _ReplicaManager.Contract.LocalDomain(&_ReplicaManager.CallOpts) +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableSession) Owner() (common.Address, error) { + return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) } // Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // // Solidity: function owner() view returns(address) -func (_ReplicaManager *ReplicaManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +func (_OwnableUpgradeable *OwnableUpgradeableCallerSession) Owner() (common.Address, error) { + return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function owner() view returns(address) -func (_ReplicaManager *ReplicaManagerSession) Owner() (common.Address, error) { - return _ReplicaManager.Contract.Owner(&_ReplicaManager.CallOpts) +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.contract.Transact(opts, "renounceOwnership") } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function owner() view returns(address) -func (_ReplicaManager *ReplicaManagerCallerSession) Owner() (common.Address, error) { - return _ReplicaManager.Contract.Owner(&_ReplicaManager.CallOpts) +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManager *ReplicaManagerCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "systemMessenger") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManager *ReplicaManagerSession) SystemMessenger() (common.Address, error) { - return _ReplicaManager.Contract.SystemMessenger(&_ReplicaManager.CallOpts) +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManager *ReplicaManagerCallerSession) SystemMessenger() (common.Address, error) { - return _ReplicaManager.Contract.SystemMessenger(&_ReplicaManager.CallOpts) +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function updater() view returns(address) -func (_ReplicaManager *ReplicaManagerCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "updater") - - if err != nil { - return *new(common.Address), err - } +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +} - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) +// OwnableUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the OwnableUpgradeable contract. +type OwnableUpgradeableInitializedIterator struct { + Event *OwnableUpgradeableInitialized // Event containing the contract specifics and raw log - return out0, err + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_ReplicaManager *ReplicaManagerSession) Updater() (common.Address, error) { - return _ReplicaManager.Contract.Updater(&_ReplicaManager.CallOpts) -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OwnableUpgradeableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_ReplicaManager *ReplicaManagerCallerSession) Updater() (common.Address, error) { - return _ReplicaManager.Contract.Updater(&_ReplicaManager.CallOpts) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. -// -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManager *ReplicaManagerTransactor) Initialize(opts *bind.TransactOpts, _remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "initialize", _remoteDomain, _updater) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. -// -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManager *ReplicaManagerSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.Initialize(&_ReplicaManager.TransactOpts, _remoteDomain, _updater) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OwnableUpgradeableInitializedIterator) Error() error { + return it.fail } -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. -// -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.Initialize(&_ReplicaManager.TransactOpts, _remoteDomain, _updater) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OwnableUpgradeableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. -// -// Solidity: function process(bytes _message) returns() -func (_ReplicaManager *ReplicaManagerTransactor) Process(opts *bind.TransactOpts, _message []byte) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "process", _message) +// OwnableUpgradeableInitialized represents a Initialized event raised by the OwnableUpgradeable contract. +type OwnableUpgradeableInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function process(bytes _message) returns() -func (_ReplicaManager *ReplicaManagerSession) Process(_message []byte) (*types.Transaction, error) { - return _ReplicaManager.Contract.Process(&_ReplicaManager.TransactOpts, _message) -} +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*OwnableUpgradeableInitializedIterator, error) { -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. -// -// Solidity: function process(bytes _message) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) Process(_message []byte) (*types.Transaction, error) { - return _ReplicaManager.Contract.Process(&_ReplicaManager.TransactOpts, _message) + logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &OwnableUpgradeableInitializedIterator{contract: _OwnableUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManager *ReplicaManagerTransactor) Prove(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "prove", _remoteDomain, _message, _proof, _index) -} +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableInitialized) (event.Subscription, error) { -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. -// -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManager *ReplicaManagerSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.Prove(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) -} + logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OwnableUpgradeableInitialized) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. -// -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManager *ReplicaManagerTransactorSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.Prove(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManager *ReplicaManagerTransactor) ProveAndProcess(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "proveAndProcess", _remoteDomain, _message, _proof, _index) +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseInitialized(log types.Log) (*OwnableUpgradeableInitialized, error) { + event := new(OwnableUpgradeableInitialized) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. -// -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManager *ReplicaManagerSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.ProveAndProcess(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) -} +// OwnableUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the OwnableUpgradeable contract. +type OwnableUpgradeableOwnershipTransferredIterator struct { + Event *OwnableUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. -// -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.ProveAndProcess(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManager *ReplicaManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManager *ReplicaManagerSession) RenounceOwnership() (*types.Transaction, error) { - return _ReplicaManager.Contract.RenounceOwnership(&_ReplicaManager.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _ReplicaManager.Contract.RenounceOwnership(&_ReplicaManager.TransactOpts) -} - -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManager *ReplicaManagerTransactor) SetConfirmation(opts *bind.TransactOpts, _remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "setConfirmation", _remoteDomain, _root, _confirmAt) -} - -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManager *ReplicaManagerSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetConfirmation(&_ReplicaManager.TransactOpts, _remoteDomain, _root, _confirmAt) -} - -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetConfirmation(&_ReplicaManager.TransactOpts, _remoteDomain, _root, _confirmAt) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManager *ReplicaManagerTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "setSystemMessenger", _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManager *ReplicaManagerSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetSystemMessenger(&_ReplicaManager.TransactOpts, _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetSystemMessenger(&_ReplicaManager.TransactOpts, _systemMessenger) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManager *ReplicaManagerTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "setUpdater", _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManager *ReplicaManagerSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetUpdater(&_ReplicaManager.TransactOpts, _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetUpdater(&_ReplicaManager.TransactOpts, _updater) -} - -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManager *ReplicaManagerTransactor) SubmitAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "submitAttestation", _attestation) -} - -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManager *ReplicaManagerSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { - return _ReplicaManager.Contract.SubmitAttestation(&_ReplicaManager.TransactOpts, _attestation) -} - -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { - return _ReplicaManager.Contract.SubmitAttestation(&_ReplicaManager.TransactOpts, _attestation) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManager *ReplicaManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManager *ReplicaManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.TransferOwnership(&_ReplicaManager.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.TransferOwnership(&_ReplicaManager.TransactOpts, newOwner) -} - -// ReplicaManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ReplicaManager contract. -type ReplicaManagerInitializedIterator struct { - Event *ReplicaManagerInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data logs chan types.Log // Log channel receiving the found contract events sub ethereum.Subscription // Subscription for errors, completion and termination @@ -3784,7 +4031,7 @@ type ReplicaManagerInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerInitializedIterator) Next() bool { +func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -3793,7 +4040,7 @@ func (it *ReplicaManagerInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerInitialized) + it.Event = new(OwnableUpgradeableOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3808,7 +4055,7 @@ func (it *ReplicaManagerInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerInitialized) + it.Event = new(OwnableUpgradeableOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3824,41 +4071,60 @@ func (it *ReplicaManagerInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerInitializedIterator) Error() error { +func (it *OwnableUpgradeableOwnershipTransferredIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerInitializedIterator) Close() error { +func (it *OwnableUpgradeableOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerInitialized represents a Initialized event raised by the ReplicaManager contract. -type ReplicaManagerInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// OwnableUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the OwnableUpgradeable contract. +type OwnableUpgradeableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Initialized(uint8 version) -func (_ReplicaManager *ReplicaManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ReplicaManagerInitializedIterator, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableUpgradeableOwnershipTransferredIterator, error) { - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "Initialized") + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } - return &ReplicaManagerInitializedIterator{contract: _ReplicaManager.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &OwnableUpgradeableOwnershipTransferredIterator{contract: _OwnableUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Initialized(uint8 version) -func (_ReplicaManager *ReplicaManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ReplicaManagerInitialized) (event.Subscription, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Initialized") + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } @@ -3868,8 +4134,8 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchInitialized(opts *bind.Watch select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerInitialized) - if err := _ReplicaManager.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(OwnableUpgradeableOwnershipTransferred) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -3890,110 +4156,1679 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchInitialized(opts *bind.Watch }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Initialized(uint8 version) -func (_ReplicaManager *ReplicaManagerFilterer) ParseInitialized(log types.Log) (*ReplicaManagerInitialized, error) { - event := new(ReplicaManagerInitialized) - if err := _ReplicaManager.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableUpgradeableOwnershipTransferred, error) { + event := new(OwnableUpgradeableOwnershipTransferred) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the ReplicaManager contract. -type ReplicaManagerNewUpdaterIterator struct { - Event *ReplicaManagerNewUpdater // Event containing the contract specifics and raw log +// ReplicaLibMetaData contains all meta data concerning the ReplicaLib contract. +var ReplicaLibMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"MESSAGE_STATUS_NONE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MESSAGE_STATUS_PROCESSED\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "b0075818": "MESSAGE_STATUS_NONE()", + "643d8086": "MESSAGE_STATUS_PROCESSED()", + }, + Bin: "0x6098610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212201683c62ebbfa78a6c3d195b6a065da2517221675fde0dda5f19e2b8bce0a324564736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// ReplicaLibABI is the input ABI used to generate the binding from. +// Deprecated: Use ReplicaLibMetaData.ABI instead. +var ReplicaLibABI = ReplicaLibMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// Deprecated: Use ReplicaLibMetaData.Sigs instead. +// ReplicaLibFuncSigs maps the 4-byte function signature to its string representation. +var ReplicaLibFuncSigs = ReplicaLibMetaData.Sigs -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// ReplicaLibBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ReplicaLibMetaData.Bin instead. +var ReplicaLibBin = ReplicaLibMetaData.Bin - default: - return false - } +// DeployReplicaLib deploys a new Ethereum contract, binding an instance of ReplicaLib to it. +func DeployReplicaLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ReplicaLib, error) { + parsed, err := ReplicaLibMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } -} -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerNewUpdaterIterator) Error() error { + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaLibBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ReplicaLib{ReplicaLibCaller: ReplicaLibCaller{contract: contract}, ReplicaLibTransactor: ReplicaLibTransactor{contract: contract}, ReplicaLibFilterer: ReplicaLibFilterer{contract: contract}}, nil +} + +// ReplicaLib is an auto generated Go binding around an Ethereum contract. +type ReplicaLib struct { + ReplicaLibCaller // Read-only binding to the contract + ReplicaLibTransactor // Write-only binding to the contract + ReplicaLibFilterer // Log filterer for contract events +} + +// ReplicaLibCaller is an auto generated read-only Go binding around an Ethereum contract. +type ReplicaLibCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaLibTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ReplicaLibTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ReplicaLibFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaLibSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ReplicaLibSession struct { + Contract *ReplicaLib // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ReplicaLibCallerSession struct { + Contract *ReplicaLibCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ReplicaLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ReplicaLibTransactorSession struct { + Contract *ReplicaLibTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaLibRaw is an auto generated low-level Go binding around an Ethereum contract. +type ReplicaLibRaw struct { + Contract *ReplicaLib // Generic contract binding to access the raw methods on +} + +// ReplicaLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ReplicaLibCallerRaw struct { + Contract *ReplicaLibCaller // Generic read-only contract binding to access the raw methods on +} + +// ReplicaLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ReplicaLibTransactorRaw struct { + Contract *ReplicaLibTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewReplicaLib creates a new instance of ReplicaLib, bound to a specific deployed contract. +func NewReplicaLib(address common.Address, backend bind.ContractBackend) (*ReplicaLib, error) { + contract, err := bindReplicaLib(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ReplicaLib{ReplicaLibCaller: ReplicaLibCaller{contract: contract}, ReplicaLibTransactor: ReplicaLibTransactor{contract: contract}, ReplicaLibFilterer: ReplicaLibFilterer{contract: contract}}, nil +} + +// NewReplicaLibCaller creates a new read-only instance of ReplicaLib, bound to a specific deployed contract. +func NewReplicaLibCaller(address common.Address, caller bind.ContractCaller) (*ReplicaLibCaller, error) { + contract, err := bindReplicaLib(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ReplicaLibCaller{contract: contract}, nil +} + +// NewReplicaLibTransactor creates a new write-only instance of ReplicaLib, bound to a specific deployed contract. +func NewReplicaLibTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaLibTransactor, error) { + contract, err := bindReplicaLib(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ReplicaLibTransactor{contract: contract}, nil +} + +// NewReplicaLibFilterer creates a new log filterer instance of ReplicaLib, bound to a specific deployed contract. +func NewReplicaLibFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaLibFilterer, error) { + contract, err := bindReplicaLib(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ReplicaLibFilterer{contract: contract}, nil +} + +// bindReplicaLib binds a generic wrapper to an already deployed contract. +func bindReplicaLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ReplicaLibABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaLib *ReplicaLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaLib.Contract.ReplicaLibCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaLib *ReplicaLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaLib.Contract.ReplicaLibTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaLib *ReplicaLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaLib.Contract.ReplicaLibTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaLib *ReplicaLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaLib.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaLib *ReplicaLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaLib.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaLib *ReplicaLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaLib.Contract.contract.Transact(opts, method, params...) +} + +// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. +// +// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) +func (_ReplicaLib *ReplicaLibCaller) MESSAGESTATUSNONE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ReplicaLib.contract.Call(opts, &out, "MESSAGE_STATUS_NONE") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. +// +// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) +func (_ReplicaLib *ReplicaLibSession) MESSAGESTATUSNONE() ([32]byte, error) { + return _ReplicaLib.Contract.MESSAGESTATUSNONE(&_ReplicaLib.CallOpts) +} + +// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. +// +// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) +func (_ReplicaLib *ReplicaLibCallerSession) MESSAGESTATUSNONE() ([32]byte, error) { + return _ReplicaLib.Contract.MESSAGESTATUSNONE(&_ReplicaLib.CallOpts) +} + +// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. +// +// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) +func (_ReplicaLib *ReplicaLibCaller) MESSAGESTATUSPROCESSED(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ReplicaLib.contract.Call(opts, &out, "MESSAGE_STATUS_PROCESSED") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. +// +// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) +func (_ReplicaLib *ReplicaLibSession) MESSAGESTATUSPROCESSED() ([32]byte, error) { + return _ReplicaLib.Contract.MESSAGESTATUSPROCESSED(&_ReplicaLib.CallOpts) +} + +// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. +// +// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) +func (_ReplicaLib *ReplicaLibCallerSession) MESSAGESTATUSPROCESSED() ([32]byte, error) { + return _ReplicaLib.Contract.MESSAGESTATUSPROCESSED(&_ReplicaLib.CallOpts) +} + +// ReplicaManagerMetaData contains all meta data concerning the ReplicaManager contract. +var ReplicaManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"AttestationAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "ffa1ad74": "VERSION()", + "15a046aa": "acceptableRoot(uint32,uint32,bytes32)", + "7dfdba28": "activeReplicaConfirmedAt(uint32,bytes32)", + "63415514": "activeReplicaMessageStatus(uint32,bytes32)", + "b65672d3": "activeReplicaNonce(uint32)", + "9fe03fa2": "allGuards()", + "629ddf69": "getGuard(uint256)", + "246c2449": "guardsAmount()", + "8624c35c": "initialize(uint32,address)", + "8d3638f4": "localDomain()", + "8da5cb5b": "owner()", + "928bc4b2": "process(bytes)", + "4f63be3f": "prove(uint32,bytes,bytes32[32],uint256)", + "68705275": "proveAndProcess(uint32,bytes,bytes32[32],uint256)", + "715018a6": "renounceOwnership()", + "9df7d36d": "setConfirmation(uint32,bytes32,uint256)", + "b7bc563e": "setSystemMessenger(address)", + "61bc3111": "setUpdater(uint32,address)", + "f646a512": "submitAttestation(bytes)", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + }, + Bin: "0x60a06040523480156200001157600080fd5b5060405162002f5238038062002f52833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612eb66200009c600039600081816102cf015281816109240152610f310152612eb66000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638d3638f4116100d8578063b65672d31161008c578063f2fde38b11610066578063f2fde38b146103c8578063f646a512146103db578063ffa1ad74146103ee57600080fd5b8063b65672d31461035f578063b7bc563e14610395578063ccbdf9c9146103a857600080fd5b8063928bc4b2116100bd578063928bc4b2146103245780639df7d36d146103375780639fe03fa21461034a57600080fd5b80638d3638f4146102ca5780638da5cb5b1461030657600080fd5b8063634155141161012f578063715018a611610114578063715018a61461026e5780637dfdba28146102765780638624c35c146102b757600080fd5b8063634155141461021a578063687052751461025b57600080fd5b80634f63be3f116101605780634f63be3f146101ba57806361bc3111146101cd578063629ddf69146101e257600080fd5b806315a046aa1461017c578063246c2449146101a4575b600080fd5b61018f61018a366004612824565b610408565b60405190151581526020015b60405180910390f35b6101ac610465565b60405190815260200161019b565b61018f6101c836600461293a565b610476565b6101e06101db3660046129cc565b6105f0565b005b6101f56101f0366004612a03565b610666565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101ac610228366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b6101e061026936600461293a565b610679565b6101e06106e0565b6101ac610284366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b6101e06102c53660046129cc565b610749565b6102f17f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019b565b60335473ffffffffffffffffffffffffffffffffffffffff166101f5565b6101e0610332366004612a46565b6108cb565b6101e0610345366004612a7b565b610c67565b610352610d5b565b60405161019b9190612aae565b6102f161036d366004612b08565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b6101e06103a3366004612b23565b610d67565b6065546101f59073ffffffffffffffffffffffffffffffffffffffff1681565b6101e06103d6366004612b23565b610e15565b6101e06103e9366004612a46565b610f0e565b6103f6600081565b60405160ff909116815260200161019b565b63ffffffff8316600090815260ce6020908152604080832054835260cd825280832084845260010190915281205480820361044757600091505061045e565b61045763ffffffff851682612b6f565b4210159150505b9392505050565b600061047160986110e9565b905090565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff1660028111156104c5576104c5612b87565b146105175760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105755760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e6500000000000000000000000000604482015260640161050e565b60006105ab8387602080602002604051908101604052809291908260208002808284376000920191909152508991506110f39050565b6000818152600184016020526040902054909150156105e05760009283526002919091016020526040909120555060016105e8565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106575760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b6106618282611199565b505050565b6000610673609883611296565b92915050565b61068584848484610476565b6106d15760405162461bcd60e51b815260206004820152600660248201527f2170726f76650000000000000000000000000000000000000000000000000000604482015260640161050e565b6106da836108cb565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b565b600061075560016112a2565b9050801561078a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6107926113f9565b61079c8383611199565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561084e8360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561066157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60006108d68261147e565b905060006108e962ffffff19831661148c565b905060006108fc62ffffff1983166114cc565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661095362ffffff1985166114f6565b63ffffffff16146109a65760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e0000000000000000000000000000000000000000604482015260640161050e565b60006109b762ffffff198616611517565b60008181526002840160205260409020549091506109d481611574565b610a205760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f636573736564000000000000000000000000604482015260640161050e565b610a3984610a3362ffffff198816611588565b83610408565b610a855760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e64730000000000000000000000000000604482015260640161050e565b60cb5460ff16600114610ada5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e7400000000000000000000000000000000000000000000604482015260640161050e565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b17610b1462ffffff1988166115a9565b50565b6000828152600284016020526040812060019055610b42610b3d62ffffff1988166115e0565b611601565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b7062ffffff198a16611643565b610b7f62ffffff198b16611664565b600087815260018a016020526040902054610bad610ba262ffffff198f16611685565b62ffffff19166116c4565b6040518663ffffffff1660e01b8152600401610bcd959493929190612c21565b600060405180830381600087803b158015610be757600080fd5b505af1158015610bfb573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610d119083908690869061171716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b6060610471609861172b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e7c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b73ffffffffffffffffffffffffffffffffffffffff8116610f055760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161050e565b610b1481611738565b6000610f19826117af565b9150506000610f2d8262ffffff19166118e9565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610faa5760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e00000000604482015260640161050e565b6000610fbb62ffffff1984166118fd565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116110365760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e7420737461746500604482015260640161050e565b600061104762ffffff198616611911565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6110cc610ba28a62ffffff1916611926565b6040516110d99190612c61565b60405180910390a4505050505050565b6000610673825490565b8260005b602081101561119157600183821c16600085836020811061111a5761111a612c74565b602002015190508160010361115a576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611187565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b50506001016110f7565b509392505050565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156111dd57506000610673565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b600061045e8383611959565b60008054610100900460ff161561133f578160ff1660011480156112c55750303b155b6113375760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b506000919050565b60005460ff8084169116106113bc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114765760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b610747611983565b600061067382610539611a09565b6000816114a162ffffff198216610539611a2d565b506114c3836114b1856001611b2e565b6114bc866002611b2e565b6001611b60565b91505b50919050565b6000816114e260015b62ffffff19831690611a2d565b506114c362ffffff19841660026004611b7f565b60008161150360016114d5565b506114c362ffffff198416602a6004611b7f565b6000806115328360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061155c8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906106735750506001141590565b60008161159560016114d5565b506114c362ffffff198416604e6004611b7f565b6000816115be62ffffff198216610539611a2d565b506114c3836115ce856002611b2e565b6115d9866003611b2e565b6002611b60565b6000816115ed60016114d5565b506114c362ffffff198416602e6020611baf565b600074010000000000000000000000000000000000000000820161163d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b81610673565b60008161165060016114d5565b506114c362ffffff19841660266004611b7f565b60008161167160016114d5565b506114c362ffffff19841660066020611baf565b60008161169a62ffffff198216610539611a2d565b506114c3836116aa856003611b2e565b601886901c6bffffffffffffffffffffffff166003611b60565b60606000806116e18460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117068483602001611d6d565b508181016020016040529052919050565b600091825260019092016020526040902055565b6060600061045e83611f12565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806117bc8382611a09565b905060286bffffffffffffffffffffffff601883901c16116118205760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161050e565b61184961183262ffffff198316611f6e565b611844610ba262ffffff198516611926565b611f83565b915061189861185d62ffffff1983166118e9565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6118e45760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161050e565b915091565b600061067362ffffff198316826004611b7f565b600061067362ffffff198316600480611b7f565b600061067362ffffff19831660086020611baf565b6000610673602861194981601886901c6bffffffffffffffffffffffff16612ca3565b62ffffff19851691906000611ffa565b600082600001828154811061197057611970612c74565b9060005260206000200154905092915050565b600054610100900460ff16611a005760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b61074733611738565b815160009060208401611a2464ffffffffff85168284612070565b95945050505050565b6000611a3983836120b7565b611b27576000611a58611a4c8560d81c90565b64ffffffffff166120da565b9150506000611a6d8464ffffffffff166120da565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161050e9190612c61565b5090919050565b600061045e6002836004811115611b4757611b47612b87565b611b519190612cba565b62ffffff198516906002611b7f565b6000611a2484611b708186612ca3565b62ffffff198816919085611ffa565b6000611b8c826020612cf7565b611b97906008612d1a565b60ff16611ba5858585611baf565b901c949350505050565b60008160ff16600003611bc45750600061045e565b611bdc8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611bf760ff841685612b6f565b1115611c6f57611c56611c188560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611c3e8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166121c4565b60405162461bcd60e51b815260040161050e9190612c61565b60208260ff161115611ce95760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161050e565b600882026000611d078660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611dea5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161050e565b611df383612232565b611e655760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161050e565b6000611e7f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611ea98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611ece5760206060fd5b8285848460045afa50611f08611ee48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611f6257602002820191906000526020600020905b815481526020019060010190808311611f4e575b50505050509050919050565b600061067362ffffff19831682602881611ffa565b600080611f9562ffffff198516611517565b9050611fee816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506105e8818461226f565b6000806120158660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061202e8661228b565b846120398784612b6f565b6120439190612b6f565b11156120565762ffffff199150506105e8565b6120608582612b6f565b9050611f088364ffffffffff1682865b60008061207d8385612b6f565b905060405181111561208d575060005b806000036120a25762ffffff1991505061045e565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166120cb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561214d5760006120f9826008612d1a565b60ff1685901c905061210a816122d3565b61ffff16841793508160ff1660101461212557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016120e0565b50600f5b60ff8160ff1610156121be57600061216a826008612d1a565b60ff1685901c905061217b816122d3565b61ffff16831792508160ff1660001461219657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612151565b50915091565b606060006121d1866120da565b91505060006121df866120da565b91505060006121ed866120da565b91505060006121fb866120da565b915050838383836040516020016122159493929190612d43565b604051602081830303815290604052945050505050949350505050565b600061223e8260d81c90565b64ffffffffff1664ffffffffff0361225857506000919050565b60006122638361228b565b60405110199392505050565b600080600061227e8585612305565b9150915061119181612373565b60006122a58260181c6bffffffffffffffffffffffff1690565b6122bd8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006122e560048360ff16901c61255f565b60ff1661ffff919091161760081b6122fc8261255f565b60ff1617919050565b600080825160410361233b5760208301516040840151606085015160001a61232f878285856126a6565b9450945050505061236c565b825160400361236457602083015160408401516123598683836127be565b93509350505061236c565b506000905060025b9250929050565b600081600481111561238757612387612b87565b0361238f5750565b60018160048111156123a3576123a3612b87565b036123f05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161050e565b600281600481111561240457612404612b87565b036124515760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161050e565b600381600481111561246557612465612b87565b036124d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b60048160048111156124ec576124ec612b87565b03610b145760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b600060f08083179060ff8216900361257a5750603092915050565b8060ff1660f10361258e5750603192915050565b8060ff1660f2036125a25750603292915050565b8060ff1660f3036125b65750603392915050565b8060ff1660f4036125ca5750603492915050565b8060ff1660f5036125de5750603592915050565b8060ff1660f6036125f25750603692915050565b8060ff1660f7036126065750603792915050565b8060ff1660f80361261a5750603892915050565b8060ff1660f90361262e5750603992915050565b8060ff1660fa036126425750606192915050565b8060ff1660fb036126565750606292915050565b8060ff1660fc0361266a5750606392915050565b8060ff1660fd0361267e5750606492915050565b8060ff1660fe036126925750606592915050565b8060ff1660ff036114c65750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126dd57506000905060036127b5565b8460ff16601b141580156126f557508460ff16601c14155b1561270657506000905060046127b5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561275a573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166127ae576000600192509250506127b5565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816127f460ff86901c601b612b6f565b9050612802878288856126a6565b935093505050935093915050565b803563ffffffff811681146113f457600080fd5b60008060006060848603121561283957600080fd5b61284284612810565b925061285060208501612810565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126128a057600080fd5b813567ffffffffffffffff808211156128bb576128bb612860565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561290157612901612860565b8160405283815286602085880101111561291a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561295157600080fd5b61295a85612810565b9350602085013567ffffffffffffffff81111561297657600080fd5b6129828782880161288f565b93505061044085018681111561299757600080fd5b9396929550505060409290920191903590565b73ffffffffffffffffffffffffffffffffffffffff81168114610b1457600080fd5b600080604083850312156129df57600080fd5b6129e883612810565b915060208301356129f8816129aa565b809150509250929050565b600060208284031215612a1557600080fd5b5035919050565b60008060408385031215612a2f57600080fd5b612a3883612810565b946020939093013593505050565b600060208284031215612a5857600080fd5b813567ffffffffffffffff811115612a6f57600080fd5b6105e88482850161288f565b600080600060608486031215612a9057600080fd5b612a9984612810565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612afc57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612aca565b50909695505050505050565b600060208284031215612b1a57600080fd5b61045e82612810565b600060208284031215612b3557600080fd5b813561045e816129aa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612b8257612b82612b40565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612bdc57602081850181015186830182015201612bc0565b81811115612bee576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612c5660a0830184612bb6565b979650505050505050565b60208152600061045e6020830184612bb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612cb557612cb5612b40565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612cf257612cf2612b40565b500290565b600060ff821660ff841680821015612d1157612d11612b40565b90039392505050565b600060ff821660ff84168160ff0481118215151615612d3b57612d3b612b40565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611f0856fea2646970667358221220fce2fcfae6e4784100dcfa09c5fc7f416a04dc2f803ffcb15a7730e07d8204ec64736f6c634300080d0033", +} + +// ReplicaManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ReplicaManagerMetaData.ABI instead. +var ReplicaManagerABI = ReplicaManagerMetaData.ABI + +// Deprecated: Use ReplicaManagerMetaData.Sigs instead. +// ReplicaManagerFuncSigs maps the 4-byte function signature to its string representation. +var ReplicaManagerFuncSigs = ReplicaManagerMetaData.Sigs + +// ReplicaManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ReplicaManagerMetaData.Bin instead. +var ReplicaManagerBin = ReplicaManagerMetaData.Bin + +// DeployReplicaManager deploys a new Ethereum contract, binding an instance of ReplicaManager to it. +func DeployReplicaManager(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *ReplicaManager, error) { + parsed, err := ReplicaManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaManagerBin), backend, _localDomain) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ReplicaManager{ReplicaManagerCaller: ReplicaManagerCaller{contract: contract}, ReplicaManagerTransactor: ReplicaManagerTransactor{contract: contract}, ReplicaManagerFilterer: ReplicaManagerFilterer{contract: contract}}, nil +} + +// ReplicaManager is an auto generated Go binding around an Ethereum contract. +type ReplicaManager struct { + ReplicaManagerCaller // Read-only binding to the contract + ReplicaManagerTransactor // Write-only binding to the contract + ReplicaManagerFilterer // Log filterer for contract events +} + +// ReplicaManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ReplicaManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ReplicaManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ReplicaManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ReplicaManagerSession struct { + Contract *ReplicaManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ReplicaManagerCallerSession struct { + Contract *ReplicaManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ReplicaManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ReplicaManagerTransactorSession struct { + Contract *ReplicaManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ReplicaManagerRaw struct { + Contract *ReplicaManager // Generic contract binding to access the raw methods on +} + +// ReplicaManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ReplicaManagerCallerRaw struct { + Contract *ReplicaManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ReplicaManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ReplicaManagerTransactorRaw struct { + Contract *ReplicaManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewReplicaManager creates a new instance of ReplicaManager, bound to a specific deployed contract. +func NewReplicaManager(address common.Address, backend bind.ContractBackend) (*ReplicaManager, error) { + contract, err := bindReplicaManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ReplicaManager{ReplicaManagerCaller: ReplicaManagerCaller{contract: contract}, ReplicaManagerTransactor: ReplicaManagerTransactor{contract: contract}, ReplicaManagerFilterer: ReplicaManagerFilterer{contract: contract}}, nil +} + +// NewReplicaManagerCaller creates a new read-only instance of ReplicaManager, bound to a specific deployed contract. +func NewReplicaManagerCaller(address common.Address, caller bind.ContractCaller) (*ReplicaManagerCaller, error) { + contract, err := bindReplicaManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ReplicaManagerCaller{contract: contract}, nil +} + +// NewReplicaManagerTransactor creates a new write-only instance of ReplicaManager, bound to a specific deployed contract. +func NewReplicaManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaManagerTransactor, error) { + contract, err := bindReplicaManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ReplicaManagerTransactor{contract: contract}, nil +} + +// NewReplicaManagerFilterer creates a new log filterer instance of ReplicaManager, bound to a specific deployed contract. +func NewReplicaManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaManagerFilterer, error) { + contract, err := bindReplicaManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ReplicaManagerFilterer{contract: contract}, nil +} + +// bindReplicaManager binds a generic wrapper to an already deployed contract. +func bindReplicaManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ReplicaManagerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaManager *ReplicaManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaManager.Contract.ReplicaManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaManager *ReplicaManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManager.Contract.ReplicaManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaManager *ReplicaManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaManager.Contract.ReplicaManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaManager *ReplicaManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaManager *ReplicaManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaManager *ReplicaManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaManager.Contract.contract.Transact(opts, method, params...) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManager *ReplicaManagerCaller) VERSION(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "VERSION") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManager *ReplicaManagerSession) VERSION() (uint8, error) { + return _ReplicaManager.Contract.VERSION(&_ReplicaManager.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManager *ReplicaManagerCallerSession) VERSION() (uint8, error) { + return _ReplicaManager.Contract.VERSION(&_ReplicaManager.CallOpts) +} + +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManager *ReplicaManagerCaller) AcceptableRoot(opts *bind.CallOpts, _remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "acceptableRoot", _remoteDomain, _optimisticSeconds, _root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManager *ReplicaManagerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + return _ReplicaManager.Contract.AcceptableRoot(&_ReplicaManager.CallOpts, _remoteDomain, _optimisticSeconds, _root) +} + +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManager *ReplicaManagerCallerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + return _ReplicaManager.Contract.AcceptableRoot(&_ReplicaManager.CallOpts, _remoteDomain, _optimisticSeconds, _root) +} + +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaConfirmedAt(opts *bind.CallOpts, _remoteDomain uint32, _root [32]byte) (*big.Int, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaConfirmedAt", _remoteDomain, _root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { + return _ReplicaManager.Contract.ActiveReplicaConfirmedAt(&_ReplicaManager.CallOpts, _remoteDomain, _root) +} + +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { + return _ReplicaManager.Contract.ActiveReplicaConfirmedAt(&_ReplicaManager.CallOpts, _remoteDomain, _root) +} + +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaMessageStatus(opts *bind.CallOpts, _remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaMessageStatus", _remoteDomain, _messageId) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + return _ReplicaManager.Contract.ActiveReplicaMessageStatus(&_ReplicaManager.CallOpts, _remoteDomain, _messageId) +} + +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + return _ReplicaManager.Contract.ActiveReplicaMessageStatus(&_ReplicaManager.CallOpts, _remoteDomain, _messageId) +} + +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaNonce(opts *bind.CallOpts, _remoteDomain uint32) (uint32, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaNonce", _remoteDomain) + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { + return _ReplicaManager.Contract.ActiveReplicaNonce(&_ReplicaManager.CallOpts, _remoteDomain) +} + +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { + return _ReplicaManager.Contract.ActiveReplicaNonce(&_ReplicaManager.CallOpts, _remoteDomain) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManager *ReplicaManagerCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "allGuards") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManager *ReplicaManagerSession) AllGuards() ([]common.Address, error) { + return _ReplicaManager.Contract.AllGuards(&_ReplicaManager.CallOpts) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManager *ReplicaManagerCallerSession) AllGuards() ([]common.Address, error) { + return _ReplicaManager.Contract.AllGuards(&_ReplicaManager.CallOpts) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManager *ReplicaManagerCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "getGuard", _index) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManager *ReplicaManagerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _ReplicaManager.Contract.GetGuard(&_ReplicaManager.CallOpts, _index) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManager *ReplicaManagerCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _ReplicaManager.Contract.GetGuard(&_ReplicaManager.CallOpts, _index) +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManager *ReplicaManagerCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "guardsAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManager *ReplicaManagerSession) GuardsAmount() (*big.Int, error) { + return _ReplicaManager.Contract.GuardsAmount(&_ReplicaManager.CallOpts) +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManager *ReplicaManagerCallerSession) GuardsAmount() (*big.Int, error) { + return _ReplicaManager.Contract.GuardsAmount(&_ReplicaManager.CallOpts) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManager *ReplicaManagerCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManager *ReplicaManagerSession) LocalDomain() (uint32, error) { + return _ReplicaManager.Contract.LocalDomain(&_ReplicaManager.CallOpts) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManager *ReplicaManagerCallerSession) LocalDomain() (uint32, error) { + return _ReplicaManager.Contract.LocalDomain(&_ReplicaManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManager *ReplicaManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManager *ReplicaManagerSession) Owner() (common.Address, error) { + return _ReplicaManager.Contract.Owner(&_ReplicaManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManager *ReplicaManagerCallerSession) Owner() (common.Address, error) { + return _ReplicaManager.Contract.Owner(&_ReplicaManager.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManager *ReplicaManagerCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "systemMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManager *ReplicaManagerSession) SystemMessenger() (common.Address, error) { + return _ReplicaManager.Contract.SystemMessenger(&_ReplicaManager.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManager *ReplicaManagerCallerSession) SystemMessenger() (common.Address, error) { + return _ReplicaManager.Contract.SystemMessenger(&_ReplicaManager.CallOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerTransactor) Initialize(opts *bind.TransactOpts, _remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "initialize", _remoteDomain, _updater) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.Initialize(&_ReplicaManager.TransactOpts, _remoteDomain, _updater) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.Initialize(&_ReplicaManager.TransactOpts, _remoteDomain, _updater) +} + +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// +// Solidity: function process(bytes _message) returns() +func (_ReplicaManager *ReplicaManagerTransactor) Process(opts *bind.TransactOpts, _message []byte) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "process", _message) +} + +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// +// Solidity: function process(bytes _message) returns() +func (_ReplicaManager *ReplicaManagerSession) Process(_message []byte) (*types.Transaction, error) { + return _ReplicaManager.Contract.Process(&_ReplicaManager.TransactOpts, _message) +} + +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// +// Solidity: function process(bytes _message) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) Process(_message []byte) (*types.Transaction, error) { + return _ReplicaManager.Contract.Process(&_ReplicaManager.TransactOpts, _message) +} + +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManager *ReplicaManagerTransactor) Prove(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "prove", _remoteDomain, _message, _proof, _index) +} + +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManager *ReplicaManagerSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.Prove(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) +} + +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManager *ReplicaManagerTransactorSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.Prove(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) +} + +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. +// +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManager *ReplicaManagerTransactor) ProveAndProcess(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "proveAndProcess", _remoteDomain, _message, _proof, _index) +} + +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. +// +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManager *ReplicaManagerSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.ProveAndProcess(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) +} + +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. +// +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.ProveAndProcess(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManager *ReplicaManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManager *ReplicaManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _ReplicaManager.Contract.RenounceOwnership(&_ReplicaManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ReplicaManager.Contract.RenounceOwnership(&_ReplicaManager.TransactOpts) +} + +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. +// +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManager *ReplicaManagerTransactor) SetConfirmation(opts *bind.TransactOpts, _remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "setConfirmation", _remoteDomain, _root, _confirmAt) +} + +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. +// +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManager *ReplicaManagerSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetConfirmation(&_ReplicaManager.TransactOpts, _remoteDomain, _root, _confirmAt) +} + +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. +// +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetConfirmation(&_ReplicaManager.TransactOpts, _remoteDomain, _root, _confirmAt) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManager *ReplicaManagerTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManager *ReplicaManagerSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetSystemMessenger(&_ReplicaManager.TransactOpts, _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetSystemMessenger(&_ReplicaManager.TransactOpts, _systemMessenger) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. +// +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerTransactor) SetUpdater(opts *bind.TransactOpts, _domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "setUpdater", _domain, _updater) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. +// +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerSession) SetUpdater(_domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetUpdater(&_ReplicaManager.TransactOpts, _domain, _updater) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. +// +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) SetUpdater(_domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetUpdater(&_ReplicaManager.TransactOpts, _domain, _updater) +} + +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. +// +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManager *ReplicaManagerTransactor) SubmitAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "submitAttestation", _attestation) +} + +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. +// +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManager *ReplicaManagerSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { + return _ReplicaManager.Contract.SubmitAttestation(&_ReplicaManager.TransactOpts, _attestation) +} + +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. +// +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { + return _ReplicaManager.Contract.SubmitAttestation(&_ReplicaManager.TransactOpts, _attestation) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManager *ReplicaManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManager *ReplicaManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.TransferOwnership(&_ReplicaManager.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.TransferOwnership(&_ReplicaManager.TransactOpts, newOwner) +} + +// ReplicaManagerAttestationAcceptedIterator is returned from FilterAttestationAccepted and is used to iterate over the raw logs and unpacked data for AttestationAccepted events raised by the ReplicaManager contract. +type ReplicaManagerAttestationAcceptedIterator struct { + Event *ReplicaManagerAttestationAccepted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerAttestationAcceptedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerAttestationAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerAttestationAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerAttestationAcceptedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerAttestationAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerAttestationAccepted represents a AttestationAccepted event raised by the ReplicaManager contract. +type ReplicaManagerAttestationAccepted struct { + HomeDomain uint32 + Nonce uint32 + Root [32]byte + Signature []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAttestationAccepted is a free log retrieval operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. +// +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManager *ReplicaManagerFilterer) FilterAttestationAccepted(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*ReplicaManagerAttestationAcceptedIterator, error) { + + var homeDomainRule []interface{} + for _, homeDomainItem := range homeDomain { + homeDomainRule = append(homeDomainRule, homeDomainItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var rootRule []interface{} + for _, rootItem := range root { + rootRule = append(rootRule, rootItem) + } + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "AttestationAccepted", homeDomainRule, nonceRule, rootRule) + if err != nil { + return nil, err + } + return &ReplicaManagerAttestationAcceptedIterator{contract: _ReplicaManager.contract, event: "AttestationAccepted", logs: logs, sub: sub}, nil +} + +// WatchAttestationAccepted is a free log subscription operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. +// +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManager *ReplicaManagerFilterer) WatchAttestationAccepted(opts *bind.WatchOpts, sink chan<- *ReplicaManagerAttestationAccepted, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { + + var homeDomainRule []interface{} + for _, homeDomainItem := range homeDomain { + homeDomainRule = append(homeDomainRule, homeDomainItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var rootRule []interface{} + for _, rootItem := range root { + rootRule = append(rootRule, rootItem) + } + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "AttestationAccepted", homeDomainRule, nonceRule, rootRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerAttestationAccepted) + if err := _ReplicaManager.contract.UnpackLog(event, "AttestationAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAttestationAccepted is a log parse operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. +// +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManager *ReplicaManagerFilterer) ParseAttestationAccepted(log types.Log) (*ReplicaManagerAttestationAccepted, error) { + event := new(ReplicaManagerAttestationAccepted) + if err := _ReplicaManager.contract.UnpackLog(event, "AttestationAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the ReplicaManager contract. +type ReplicaManagerGuardAddedIterator struct { + Event *ReplicaManagerGuardAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerGuardAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerGuardAdded represents a GuardAdded event raised by the ReplicaManager contract. +type ReplicaManagerGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*ReplicaManagerGuardAddedIterator, error) { + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return &ReplicaManagerGuardAddedIterator{contract: _ReplicaManager.contract, event: "GuardAdded", logs: logs, sub: sub}, nil +} + +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *ReplicaManagerGuardAdded) (event.Subscription, error) { + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerGuardAdded) + if err := _ReplicaManager.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) ParseGuardAdded(log types.Log) (*ReplicaManagerGuardAdded, error) { + event := new(ReplicaManagerGuardAdded) + if err := _ReplicaManager.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the ReplicaManager contract. +type ReplicaManagerGuardRemovedIterator struct { + Event *ReplicaManagerGuardRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerGuardRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerGuardRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerGuardRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerGuardRemoved represents a GuardRemoved event raised by the ReplicaManager contract. +type ReplicaManagerGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*ReplicaManagerGuardRemovedIterator, error) { + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return &ReplicaManagerGuardRemovedIterator{contract: _ReplicaManager.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil +} + +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *ReplicaManagerGuardRemoved) (event.Subscription, error) { + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerGuardRemoved) + if err := _ReplicaManager.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) ParseGuardRemoved(log types.Log) (*ReplicaManagerGuardRemoved, error) { + event := new(ReplicaManagerGuardRemoved) + if err := _ReplicaManager.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ReplicaManager contract. +type ReplicaManagerInitializedIterator struct { + Event *ReplicaManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerInitialized represents a Initialized event raised by the ReplicaManager contract. +type ReplicaManagerInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_ReplicaManager *ReplicaManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ReplicaManagerInitializedIterator, error) { + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ReplicaManagerInitializedIterator{contract: _ReplicaManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_ReplicaManager *ReplicaManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ReplicaManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerInitialized) + if err := _ReplicaManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_ReplicaManager *ReplicaManagerFilterer) ParseInitialized(log types.Log) (*ReplicaManagerInitialized, error) { + event := new(ReplicaManagerInitialized) + if err := _ReplicaManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerNotaryAddedIterator is returned from FilterNotaryAdded and is used to iterate over the raw logs and unpacked data for NotaryAdded events raised by the ReplicaManager contract. +type ReplicaManagerNotaryAddedIterator struct { + Event *ReplicaManagerNotaryAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerNotaryAddedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerNewUpdaterIterator) Close() error { +func (it *ReplicaManagerNotaryAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerNewUpdater represents a NewUpdater event raised by the ReplicaManager contract. -type ReplicaManagerNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerNotaryAdded represents a NotaryAdded event raised by the ReplicaManager contract. +type ReplicaManagerNotaryAdded struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// FilterNotaryAdded is a free log retrieval operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManager *ReplicaManagerFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*ReplicaManagerNewUpdaterIterator, error) { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) FilterNotaryAdded(opts *bind.FilterOpts, domain []uint32) (*ReplicaManagerNotaryAddedIterator, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "NewUpdater") + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "NotaryAdded", domainRule) if err != nil { return nil, err } - return &ReplicaManagerNewUpdaterIterator{contract: _ReplicaManager.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &ReplicaManagerNotaryAddedIterator{contract: _ReplicaManager.contract, event: "NotaryAdded", logs: logs, sub: sub}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// WatchNotaryAdded is a free log subscription operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManager *ReplicaManagerFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *ReplicaManagerNewUpdater) (event.Subscription, error) { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) WatchNotaryAdded(opts *bind.WatchOpts, sink chan<- *ReplicaManagerNotaryAdded, domain []uint32) (event.Subscription, error) { - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "NewUpdater") + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "NotaryAdded", domainRule) if err != nil { return nil, err } @@ -4003,8 +5838,8 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchNewUpdater(opts *bind.WatchO select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerNewUpdater) - if err := _ReplicaManager.contract.UnpackLog(event, "NewUpdater", log); err != nil { + event := new(ReplicaManagerNotaryAdded) + if err := _ReplicaManager.contract.UnpackLog(event, "NotaryAdded", log); err != nil { return err } event.Raw = log @@ -4025,21 +5860,21 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchNewUpdater(opts *bind.WatchO }), nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// ParseNotaryAdded is a log parse operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManager *ReplicaManagerFilterer) ParseNewUpdater(log types.Log) (*ReplicaManagerNewUpdater, error) { - event := new(ReplicaManagerNewUpdater) - if err := _ReplicaManager.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) ParseNotaryAdded(log types.Log) (*ReplicaManagerNotaryAdded, error) { + event := new(ReplicaManagerNotaryAdded) + if err := _ReplicaManager.contract.UnpackLog(event, "NotaryAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ReplicaManager contract. -type ReplicaManagerOwnershipTransferredIterator struct { - Event *ReplicaManagerOwnershipTransferred // Event containing the contract specifics and raw log +// ReplicaManagerNotaryRemovedIterator is returned from FilterNotaryRemoved and is used to iterate over the raw logs and unpacked data for NotaryRemoved events raised by the ReplicaManager contract. +type ReplicaManagerNotaryRemovedIterator struct { + Event *ReplicaManagerNotaryRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4053,7 +5888,7 @@ type ReplicaManagerOwnershipTransferredIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerOwnershipTransferredIterator) Next() bool { +func (it *ReplicaManagerNotaryRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4062,7 +5897,7 @@ func (it *ReplicaManagerOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerOwnershipTransferred) + it.Event = new(ReplicaManagerNotaryRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4077,7 +5912,7 @@ func (it *ReplicaManagerOwnershipTransferredIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerOwnershipTransferred) + it.Event = new(ReplicaManagerNotaryRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4093,60 +5928,52 @@ func (it *ReplicaManagerOwnershipTransferredIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerOwnershipTransferredIterator) Error() error { +func (it *ReplicaManagerNotaryRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerOwnershipTransferredIterator) Close() error { +func (it *ReplicaManagerNotaryRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerOwnershipTransferred represents a OwnershipTransferred event raised by the ReplicaManager contract. -type ReplicaManagerOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerNotaryRemoved represents a NotaryRemoved event raised by the ReplicaManager contract. +type ReplicaManagerNotaryRemoved struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// FilterNotaryRemoved is a free log retrieval operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_ReplicaManager *ReplicaManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ReplicaManagerOwnershipTransferredIterator, error) { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) FilterNotaryRemoved(opts *bind.FilterOpts, domain []uint32) (*ReplicaManagerNotaryRemovedIterator, error) { - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) } - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "NotaryRemoved", domainRule) if err != nil { return nil, err } - return &ReplicaManagerOwnershipTransferredIterator{contract: _ReplicaManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &ReplicaManagerNotaryRemovedIterator{contract: _ReplicaManager.contract, event: "NotaryRemoved", logs: logs, sub: sub}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// WatchNotaryRemoved is a free log subscription operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_ReplicaManager *ReplicaManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ReplicaManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) WatchNotaryRemoved(opts *bind.WatchOpts, sink chan<- *ReplicaManagerNotaryRemoved, domain []uint32) (event.Subscription, error) { - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) } - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "NotaryRemoved", domainRule) if err != nil { return nil, err } @@ -4156,8 +5983,8 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchOwnershipTransferred(opts *b select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerOwnershipTransferred) - if err := _ReplicaManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(ReplicaManagerNotaryRemoved) + if err := _ReplicaManager.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { return err } event.Raw = log @@ -4178,21 +6005,21 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchOwnershipTransferred(opts *b }), nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// ParseNotaryRemoved is a log parse operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_ReplicaManager *ReplicaManagerFilterer) ParseOwnershipTransferred(log types.Log) (*ReplicaManagerOwnershipTransferred, error) { - event := new(ReplicaManagerOwnershipTransferred) - if err := _ReplicaManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) ParseNotaryRemoved(log types.Log) (*ReplicaManagerNotaryRemoved, error) { + event := new(ReplicaManagerNotaryRemoved) + if err := _ReplicaManager.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerProcessIterator is returned from FilterProcess and is used to iterate over the raw logs and unpacked data for Process events raised by the ReplicaManager contract. -type ReplicaManagerProcessIterator struct { - Event *ReplicaManagerProcess // Event containing the contract specifics and raw log +// ReplicaManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ReplicaManager contract. +type ReplicaManagerOwnershipTransferredIterator struct { + Event *ReplicaManagerOwnershipTransferred // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4206,7 +6033,7 @@ type ReplicaManagerProcessIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerProcessIterator) Next() bool { +func (it *ReplicaManagerOwnershipTransferredIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4215,7 +6042,7 @@ func (it *ReplicaManagerProcessIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerProcess) + it.Event = new(ReplicaManagerOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4230,7 +6057,7 @@ func (it *ReplicaManagerProcessIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerProcess) + it.Event = new(ReplicaManagerOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4246,60 +6073,60 @@ func (it *ReplicaManagerProcessIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerProcessIterator) Error() error { +func (it *ReplicaManagerOwnershipTransferredIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerProcessIterator) Close() error { +func (it *ReplicaManagerOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerProcess represents a Process event raised by the ReplicaManager contract. -type ReplicaManagerProcess struct { - RemoteDomain uint32 - MessageHash [32]byte - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerOwnershipTransferred represents a OwnershipTransferred event raised by the ReplicaManager contract. +type ReplicaManagerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterProcess is a free log retrieval operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) -func (_ReplicaManager *ReplicaManagerFilterer) FilterProcess(opts *bind.FilterOpts, remoteDomain []uint32, messageHash [][32]byte) (*ReplicaManagerProcessIterator, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ReplicaManager *ReplicaManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ReplicaManagerOwnershipTransferredIterator, error) { - var remoteDomainRule []interface{} - for _, remoteDomainItem := range remoteDomain { - remoteDomainRule = append(remoteDomainRule, remoteDomainItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "Process", remoteDomainRule, messageHashRule) + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } - return &ReplicaManagerProcessIterator{contract: _ReplicaManager.contract, event: "Process", logs: logs, sub: sub}, nil + return &ReplicaManagerOwnershipTransferredIterator{contract: _ReplicaManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// WatchProcess is a free log subscription operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) -func (_ReplicaManager *ReplicaManagerFilterer) WatchProcess(opts *bind.WatchOpts, sink chan<- *ReplicaManagerProcess, remoteDomain []uint32, messageHash [][32]byte) (event.Subscription, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ReplicaManager *ReplicaManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ReplicaManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - var remoteDomainRule []interface{} - for _, remoteDomainItem := range remoteDomain { - remoteDomainRule = append(remoteDomainRule, remoteDomainItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Process", remoteDomainRule, messageHashRule) + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } @@ -4309,8 +6136,8 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchProcess(opts *bind.WatchOpts select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerProcess) - if err := _ReplicaManager.contract.UnpackLog(event, "Process", log); err != nil { + event := new(ReplicaManagerOwnershipTransferred) + if err := _ReplicaManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -4331,21 +6158,21 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchProcess(opts *bind.WatchOpts }), nil } -// ParseProcess is a log parse operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) -func (_ReplicaManager *ReplicaManagerFilterer) ParseProcess(log types.Log) (*ReplicaManagerProcess, error) { - event := new(ReplicaManagerProcess) - if err := _ReplicaManager.contract.UnpackLog(event, "Process", log); err != nil { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ReplicaManager *ReplicaManagerFilterer) ParseOwnershipTransferred(log types.Log) (*ReplicaManagerOwnershipTransferred, error) { + event := new(ReplicaManagerOwnershipTransferred) + if err := _ReplicaManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerSetConfirmationIterator is returned from FilterSetConfirmation and is used to iterate over the raw logs and unpacked data for SetConfirmation events raised by the ReplicaManager contract. -type ReplicaManagerSetConfirmationIterator struct { - Event *ReplicaManagerSetConfirmation // Event containing the contract specifics and raw log +// ReplicaManagerProcessIterator is returned from FilterProcess and is used to iterate over the raw logs and unpacked data for Process events raised by the ReplicaManager contract. +type ReplicaManagerProcessIterator struct { + Event *ReplicaManagerProcess // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4359,7 +6186,7 @@ type ReplicaManagerSetConfirmationIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerSetConfirmationIterator) Next() bool { +func (it *ReplicaManagerProcessIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4368,7 +6195,7 @@ func (it *ReplicaManagerSetConfirmationIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerSetConfirmation) + it.Event = new(ReplicaManagerProcess) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4383,7 +6210,7 @@ func (it *ReplicaManagerSetConfirmationIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerSetConfirmation) + it.Event = new(ReplicaManagerProcess) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4399,62 +6226,60 @@ func (it *ReplicaManagerSetConfirmationIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerSetConfirmationIterator) Error() error { +func (it *ReplicaManagerProcessIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerSetConfirmationIterator) Close() error { +func (it *ReplicaManagerProcessIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerSetConfirmation represents a SetConfirmation event raised by the ReplicaManager contract. -type ReplicaManagerSetConfirmation struct { - RemoteDomain uint32 - Root [32]byte - PreviousConfirmAt *big.Int - NewConfirmAt *big.Int - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerProcess represents a Process event raised by the ReplicaManager contract. +type ReplicaManagerProcess struct { + RemoteDomain uint32 + MessageHash [32]byte + Raw types.Log // Blockchain specific contextual infos } -// FilterSetConfirmation is a free log retrieval operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// FilterProcess is a free log retrieval operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. // -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManager *ReplicaManagerFilterer) FilterSetConfirmation(opts *bind.FilterOpts, remoteDomain []uint32, root [][32]byte) (*ReplicaManagerSetConfirmationIterator, error) { +// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) +func (_ReplicaManager *ReplicaManagerFilterer) FilterProcess(opts *bind.FilterOpts, remoteDomain []uint32, messageHash [][32]byte) (*ReplicaManagerProcessIterator, error) { var remoteDomainRule []interface{} for _, remoteDomainItem := range remoteDomain { remoteDomainRule = append(remoteDomainRule, remoteDomainItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) } - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "Process", remoteDomainRule, messageHashRule) if err != nil { return nil, err } - return &ReplicaManagerSetConfirmationIterator{contract: _ReplicaManager.contract, event: "SetConfirmation", logs: logs, sub: sub}, nil + return &ReplicaManagerProcessIterator{contract: _ReplicaManager.contract, event: "Process", logs: logs, sub: sub}, nil } -// WatchSetConfirmation is a free log subscription operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// WatchProcess is a free log subscription operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. // -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManager *ReplicaManagerFilterer) WatchSetConfirmation(opts *bind.WatchOpts, sink chan<- *ReplicaManagerSetConfirmation, remoteDomain []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) +func (_ReplicaManager *ReplicaManagerFilterer) WatchProcess(opts *bind.WatchOpts, sink chan<- *ReplicaManagerProcess, remoteDomain []uint32, messageHash [][32]byte) (event.Subscription, error) { var remoteDomainRule []interface{} for _, remoteDomainItem := range remoteDomain { remoteDomainRule = append(remoteDomainRule, remoteDomainItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) } - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Process", remoteDomainRule, messageHashRule) if err != nil { return nil, err } @@ -4464,8 +6289,8 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchSetConfirmation(opts *bind.W select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerSetConfirmation) - if err := _ReplicaManager.contract.UnpackLog(event, "SetConfirmation", log); err != nil { + event := new(ReplicaManagerProcess) + if err := _ReplicaManager.contract.UnpackLog(event, "Process", log); err != nil { return err } event.Raw = log @@ -4486,21 +6311,21 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchSetConfirmation(opts *bind.W }), nil } -// ParseSetConfirmation is a log parse operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. -// -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManager *ReplicaManagerFilterer) ParseSetConfirmation(log types.Log) (*ReplicaManagerSetConfirmation, error) { - event := new(ReplicaManagerSetConfirmation) - if err := _ReplicaManager.contract.UnpackLog(event, "SetConfirmation", log); err != nil { +// ParseProcess is a log parse operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// +// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) +func (_ReplicaManager *ReplicaManagerFilterer) ParseProcess(log types.Log) (*ReplicaManagerProcess, error) { + event := new(ReplicaManagerProcess) + if err := _ReplicaManager.contract.UnpackLog(event, "Process", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the ReplicaManager contract. -type ReplicaManagerUpdateIterator struct { - Event *ReplicaManagerUpdate // Event containing the contract specifics and raw log +// ReplicaManagerSetConfirmationIterator is returned from FilterSetConfirmation and is used to iterate over the raw logs and unpacked data for SetConfirmation events raised by the ReplicaManager contract. +type ReplicaManagerSetConfirmationIterator struct { + Event *ReplicaManagerSetConfirmation // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4514,7 +6339,7 @@ type ReplicaManagerUpdateIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerUpdateIterator) Next() bool { +func (it *ReplicaManagerSetConfirmationIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4523,7 +6348,7 @@ func (it *ReplicaManagerUpdateIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerUpdate) + it.Event = new(ReplicaManagerSetConfirmation) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4538,7 +6363,7 @@ func (it *ReplicaManagerUpdateIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerUpdate) + it.Event = new(ReplicaManagerSetConfirmation) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4554,70 +6379,62 @@ func (it *ReplicaManagerUpdateIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerUpdateIterator) Error() error { +func (it *ReplicaManagerSetConfirmationIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerUpdateIterator) Close() error { +func (it *ReplicaManagerSetConfirmationIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerUpdate represents a Update event raised by the ReplicaManager contract. -type ReplicaManagerUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerSetConfirmation represents a SetConfirmation event raised by the ReplicaManager contract. +type ReplicaManagerSetConfirmation struct { + RemoteDomain uint32 + Root [32]byte + PreviousConfirmAt *big.Int + NewConfirmAt *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// FilterSetConfirmation is a free log retrieval operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManager *ReplicaManagerFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*ReplicaManagerUpdateIterator, error) { +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManager *ReplicaManagerFilterer) FilterSetConfirmation(opts *bind.FilterOpts, remoteDomain []uint32, root [][32]byte) (*ReplicaManagerSetConfirmationIterator, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var remoteDomainRule []interface{} + for _, remoteDomainItem := range remoteDomain { + remoteDomainRule = append(remoteDomainRule, remoteDomainItem) } var rootRule []interface{} for _, rootItem := range root { rootRule = append(rootRule, rootItem) } - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) if err != nil { return nil, err } - return &ReplicaManagerUpdateIterator{contract: _ReplicaManager.contract, event: "Update", logs: logs, sub: sub}, nil + return &ReplicaManagerSetConfirmationIterator{contract: _ReplicaManager.contract, event: "SetConfirmation", logs: logs, sub: sub}, nil } -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// WatchSetConfirmation is a free log subscription operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManager *ReplicaManagerFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *ReplicaManagerUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManager *ReplicaManagerFilterer) WatchSetConfirmation(opts *bind.WatchOpts, sink chan<- *ReplicaManagerSetConfirmation, remoteDomain []uint32, root [][32]byte) (event.Subscription, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var remoteDomainRule []interface{} + for _, remoteDomainItem := range remoteDomain { + remoteDomainRule = append(remoteDomainRule, remoteDomainItem) } var rootRule []interface{} for _, rootItem := range root { rootRule = append(rootRule, rootItem) } - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) if err != nil { return nil, err } @@ -4627,8 +6444,8 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchUpdate(opts *bind.WatchOpts, select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerUpdate) - if err := _ReplicaManager.contract.UnpackLog(event, "Update", log); err != nil { + event := new(ReplicaManagerSetConfirmation) + if err := _ReplicaManager.contract.UnpackLog(event, "SetConfirmation", log); err != nil { return err } event.Raw = log @@ -4649,12 +6466,12 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchUpdate(opts *bind.WatchOpts, }), nil } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// ParseSetConfirmation is a log parse operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManager *ReplicaManagerFilterer) ParseUpdate(log types.Log) (*ReplicaManagerUpdate, error) { - event := new(ReplicaManagerUpdate) - if err := _ReplicaManager.contract.UnpackLog(event, "Update", log); err != nil { +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManager *ReplicaManagerFilterer) ParseSetConfirmation(log types.Log) (*ReplicaManagerSetConfirmation, error) { + event := new(ReplicaManagerSetConfirmation) + if err := _ReplicaManager.contract.UnpackLog(event, "SetConfirmation", log); err != nil { return nil, err } event.Raw = log @@ -4664,7 +6481,7 @@ func (_ReplicaManager *ReplicaManagerFilterer) ParseUpdate(log types.Log) (*Repl // StringsMetaData contains all meta data concerning the Strings contract. var StringsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208f0d4c59e2f08b6ed876625d353416889edb4a17810e96f5bc4eb2b66d4c0dd064736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ee25f1552b8abf2a2770afb33509113630c944d4976a615272a0b52af2fd064d64736f6c634300080d0033", } // StringsABI is the input ABI used to generate the binding from. @@ -4834,308 +6651,125 @@ func (_Strings *StringsTransactorRaw) Transact(opts *bind.TransactOpts, method s return _Strings.Contract.contract.Transact(opts, method, params...) } -// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. -var SystemMessageMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d65f41e4095261b41dcfb6a6cca03835f684e04a6ec7338b26e37e77adab856f64736f6c634300080d0033", -} - -// SystemMessageABI is the input ABI used to generate the binding from. -// Deprecated: Use SystemMessageMetaData.ABI instead. -var SystemMessageABI = SystemMessageMetaData.ABI - -// SystemMessageBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use SystemMessageMetaData.Bin instead. -var SystemMessageBin = SystemMessageMetaData.Bin - -// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. -func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { - parsed, err := SystemMessageMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil -} - -// SystemMessage is an auto generated Go binding around an Ethereum contract. -type SystemMessage struct { - SystemMessageCaller // Read-only binding to the contract - SystemMessageTransactor // Write-only binding to the contract - SystemMessageFilterer // Log filterer for contract events -} - -// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. -type SystemMessageCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type SystemMessageTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type SystemMessageFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type SystemMessageSession struct { - Contract *SystemMessage // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type SystemMessageCallerSession struct { - Contract *SystemMessageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type SystemMessageTransactorSession struct { - Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. -type SystemMessageRaw struct { - Contract *SystemMessage // Generic contract binding to access the raw methods on -} - -// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type SystemMessageCallerRaw struct { - Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on -} - -// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type SystemMessageTransactorRaw struct { - Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { - contract, err := bindSystemMessage(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil -} - -// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { - contract, err := bindSystemMessage(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &SystemMessageCaller{contract: contract}, nil -} - -// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { - contract, err := bindSystemMessage(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &SystemMessageTransactor{contract: contract}, nil -} - -// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { - contract, err := bindSystemMessage(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &SystemMessageFilterer{contract: contract}, nil -} - -// bindSystemMessage binds a generic wrapper to an already deployed contract. -func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transact(opts, method, params...) -} - -// TipsMetaData contains all meta data concerning the Tips contract. -var TipsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e521ec16ea37dcdd777eec2db88082e2defe600aded3178caa1893559bfc321064736f6c634300080d0033", -} - -// TipsABI is the input ABI used to generate the binding from. -// Deprecated: Use TipsMetaData.ABI instead. -var TipsABI = TipsMetaData.ABI - -// TipsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TipsMetaData.Bin instead. -var TipsBin = TipsMetaData.Bin - -// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. -func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { - parsed, err := TipsMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil +// SystemContractMetaData contains all meta data concerning the SystemContract contract. +var SystemContractMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8d3638f4": "localDomain()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "b7bc563e": "setSystemMessenger(address)", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + }, } -// Tips is an auto generated Go binding around an Ethereum contract. -type Tips struct { - TipsCaller // Read-only binding to the contract - TipsTransactor // Write-only binding to the contract - TipsFilterer // Log filterer for contract events +// SystemContractABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemContractMetaData.ABI instead. +var SystemContractABI = SystemContractMetaData.ABI + +// Deprecated: Use SystemContractMetaData.Sigs instead. +// SystemContractFuncSigs maps the 4-byte function signature to its string representation. +var SystemContractFuncSigs = SystemContractMetaData.Sigs + +// SystemContract is an auto generated Go binding around an Ethereum contract. +type SystemContract struct { + SystemContractCaller // Read-only binding to the contract + SystemContractTransactor // Write-only binding to the contract + SystemContractFilterer // Log filterer for contract events } -// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TipsCaller struct { +// SystemContractCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemContractCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TipsTransactor struct { +// SystemContractTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemContractTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TipsFilterer struct { +// SystemContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemContractFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsSession is an auto generated Go binding around an Ethereum contract, +// SystemContractSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TipsSession struct { - Contract *Tips // Generic contract binding to set the session for +type SystemContractSession struct { + Contract *SystemContract // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TipsCallerSession struct { - Contract *TipsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemContractCallerSession struct { + Contract *SystemContractCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TipsTransactorSession struct { - Contract *TipsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemContractTransactorSession struct { + Contract *SystemContractTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TipsRaw struct { - Contract *Tips // Generic contract binding to access the raw methods on +// SystemContractRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemContractRaw struct { + Contract *SystemContract // Generic contract binding to access the raw methods on } -// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TipsCallerRaw struct { - Contract *TipsCaller // Generic read-only contract binding to access the raw methods on +// SystemContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemContractCallerRaw struct { + Contract *SystemContractCaller // Generic read-only contract binding to access the raw methods on } -// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TipsTransactorRaw struct { - Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on +// SystemContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemContractTransactorRaw struct { + Contract *SystemContractTransactor // Generic write-only contract binding to access the raw methods on } -// NewTips creates a new instance of Tips, bound to a specific deployed contract. -func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { - contract, err := bindTips(address, backend, backend, backend) +// NewSystemContract creates a new instance of SystemContract, bound to a specific deployed contract. +func NewSystemContract(address common.Address, backend bind.ContractBackend) (*SystemContract, error) { + contract, err := bindSystemContract(address, backend, backend, backend) if err != nil { return nil, err } - return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil + return &SystemContract{SystemContractCaller: SystemContractCaller{contract: contract}, SystemContractTransactor: SystemContractTransactor{contract: contract}, SystemContractFilterer: SystemContractFilterer{contract: contract}}, nil } -// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. -func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { - contract, err := bindTips(address, caller, nil, nil) +// NewSystemContractCaller creates a new read-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractCaller(address common.Address, caller bind.ContractCaller) (*SystemContractCaller, error) { + contract, err := bindSystemContract(address, caller, nil, nil) if err != nil { return nil, err } - return &TipsCaller{contract: contract}, nil + return &SystemContractCaller{contract: contract}, nil } -// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. -func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { - contract, err := bindTips(address, nil, transactor, nil) +// NewSystemContractTransactor creates a new write-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemContractTransactor, error) { + contract, err := bindSystemContract(address, nil, transactor, nil) if err != nil { return nil, err } - return &TipsTransactor{contract: contract}, nil + return &SystemContractTransactor{contract: contract}, nil } -// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. -func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { - contract, err := bindTips(address, nil, nil, filterer) +// NewSystemContractFilterer creates a new log filterer instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemContractFilterer, error) { + contract, err := bindSystemContract(address, nil, nil, filterer) if err != nil { return nil, err } - return &TipsFilterer{contract: contract}, nil + return &SystemContractFilterer{contract: contract}, nil } -// bindTips binds a generic wrapper to an already deployed contract. -func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TipsABI)) +// bindSystemContract binds a generic wrapper to an already deployed contract. +func bindSystemContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemContractABI)) if err != nil { return nil, err } @@ -5146,237 +6780,500 @@ func bindTips(address common.Address, caller bind.ContractCaller, transactor bin // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.SystemContractCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transfer(opts) +func (_SystemContract *SystemContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.contract.Transfer(opts) +func (_SystemContract *SystemContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transact(opts, method, params...) } -// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. -var TypeCastsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220feb3f17f48b19f33ec25881e99153f6ffb9ec133b201153a7f75af53cf26a16d64736f6c634300080d0033", +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// TypeCastsABI is the input ABI used to generate the binding from. -// Deprecated: Use TypeCastsMetaData.ABI instead. -var TypeCastsABI = TypeCastsMetaData.ABI +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} -// TypeCastsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypeCastsMetaData.Bin instead. -var TypeCastsBin = TypeCastsMetaData.Bin +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCallerSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "owner") -// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. -func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { - parsed, err := TypeCastsMetaData.GetAbi() if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + return *new(common.Address), err } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCallerSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "systemMessenger") + if err != nil { - return common.Address{}, nil, nil, err + return *new(common.Address), err } - return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// TypeCasts is an auto generated Go binding around an Ethereum contract. -type TypeCasts struct { - TypeCastsCaller // Read-only binding to the contract - TypeCastsTransactor // Write-only binding to the contract - TypeCastsFilterer // Log filterer for contract events +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypeCastsCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCallerSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypeCastsTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "renounceOwnership") } -// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypeCastsFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) } -// TypeCastsSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type TypeCastsSession struct { - Contract *TypeCasts // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "setSystemMessenger", _systemMessenger) } -// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type TypeCastsCallerSession struct { - Contract *TypeCastsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// SystemContractInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the SystemContract contract. +type SystemContractInitializedIterator struct { + Event *SystemContractInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type TypeCastsTransactorSession struct { - Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractInitializedIterator) Error() error { + return it.fail } -// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypeCastsRaw struct { - Contract *TypeCasts // Generic contract binding to access the raw methods on +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypeCastsCallerRaw struct { - Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on +// SystemContractInitialized represents a Initialized event raised by the SystemContract contract. +type SystemContractInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypeCastsTransactorRaw struct { - Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on -} +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) FilterInitialized(opts *bind.FilterOpts) (*SystemContractInitializedIterator, error) { -// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { - contract, err := bindTypeCasts(address, backend, backend, backend) + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + return &SystemContractInitializedIterator{contract: _SystemContract.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { - contract, err := bindTypeCasts(address, caller, nil, nil) +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *SystemContractInitialized) (event.Subscription, error) { + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypeCastsCaller{contract: contract}, nil + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { - contract, err := bindTypeCasts(address, nil, transactor, nil) - if err != nil { +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) ParseInitialized(log types.Log) (*SystemContractInitialized, error) { + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } - return &TypeCastsTransactor{contract: contract}, nil + event.Raw = log + return event, nil } -// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { - contract, err := bindTypeCasts(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &TypeCastsFilterer{contract: contract}, nil +// SystemContractOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the SystemContract contract. +type SystemContractOwnershipTransferredIterator struct { + Event *SystemContractOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// bindTypeCasts binds a generic wrapper to an already deployed contract. -func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) - if err != nil { - return nil, err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractOwnershipTransferredIterator) Error() error { + return it.fail } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.contract.Call(opts, result, method, params...) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transfer(opts) +// SystemContractOwnershipTransferred represents a OwnershipTransferred event raised by the SystemContract contract. +type SystemContractOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transact(opts, method, params...) +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*SystemContractOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &SystemContractOwnershipTransferredIterator{contract: _SystemContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. -var TypedMemViewMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "f26be3fc": "NULL()", - }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220252889ea99f4d060b684d11be49367f79b773b69bf36d9b36c4b93ae54d5d79064736f6c634300080d0033", +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *SystemContractOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TypedMemViewABI is the input ABI used to generate the binding from. -// Deprecated: Use TypedMemViewMetaData.ABI instead. -var TypedMemViewABI = TypedMemViewMetaData.ABI +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) ParseOwnershipTransferred(log types.Log) (*SystemContractOwnershipTransferred, error) { + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} -// Deprecated: Use TypedMemViewMetaData.Sigs instead. -// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. -var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs +// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. +var SystemMessageMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122020d737f94707ef513e072e66cdde5c16f0cac8dec58a05880ca533fed1e7795964736f6c634300080d0033", +} -// TypedMemViewBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypedMemViewMetaData.Bin instead. -var TypedMemViewBin = TypedMemViewMetaData.Bin +// SystemMessageABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemMessageMetaData.ABI instead. +var SystemMessageABI = SystemMessageMetaData.ABI -// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. -func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { - parsed, err := TypedMemViewMetaData.GetAbi() +// SystemMessageBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SystemMessageMetaData.Bin instead. +var SystemMessageBin = SystemMessageMetaData.Bin + +// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. +func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { + parsed, err := SystemMessageMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -5384,111 +7281,111 @@ func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) ( return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// TypedMemView is an auto generated Go binding around an Ethereum contract. -type TypedMemView struct { - TypedMemViewCaller // Read-only binding to the contract - TypedMemViewTransactor // Write-only binding to the contract - TypedMemViewFilterer // Log filterer for contract events +// SystemMessage is an auto generated Go binding around an Ethereum contract. +type SystemMessage struct { + SystemMessageCaller // Read-only binding to the contract + SystemMessageTransactor // Write-only binding to the contract + SystemMessageFilterer // Log filterer for contract events } -// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypedMemViewCaller struct { +// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemMessageCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypedMemViewTransactor struct { +// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemMessageTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypedMemViewFilterer struct { +// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemMessageFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// SystemMessageSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TypedMemViewSession struct { - Contract *TypedMemView // Generic contract binding to set the session for +type SystemMessageSession struct { + Contract *SystemMessage // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TypedMemViewCallerSession struct { - Contract *TypedMemViewCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemMessageCallerSession struct { + Contract *SystemMessageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TypedMemViewTransactorSession struct { - Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemMessageTransactorSession struct { + Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypedMemViewRaw struct { - Contract *TypedMemView // Generic contract binding to access the raw methods on +// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemMessageRaw struct { + Contract *SystemMessage // Generic contract binding to access the raw methods on } -// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypedMemViewCallerRaw struct { - Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on +// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemMessageCallerRaw struct { + Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on } -// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypedMemViewTransactorRaw struct { - Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on +// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemMessageTransactorRaw struct { + Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on } -// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { - contract, err := bindTypedMemView(address, backend, backend, backend) +// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { + contract, err := bindSystemMessage(address, backend, backend, backend) if err != nil { return nil, err } - return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { - contract, err := bindTypedMemView(address, caller, nil, nil) +// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { + contract, err := bindSystemMessage(address, caller, nil, nil) if err != nil { return nil, err } - return &TypedMemViewCaller{contract: contract}, nil + return &SystemMessageCaller{contract: contract}, nil } -// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { - contract, err := bindTypedMemView(address, nil, transactor, nil) +// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { + contract, err := bindSystemMessage(address, nil, transactor, nil) if err != nil { return nil, err } - return &TypedMemViewTransactor{contract: contract}, nil + return &SystemMessageTransactor{contract: contract}, nil } -// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { - contract, err := bindTypedMemView(address, nil, nil, filterer) +// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { + contract, err := bindSystemMessage(address, nil, nil, filterer) if err != nil { return nil, err } - return &TypedMemViewFilterer{contract: contract}, nil + return &SystemMessageFilterer{contract: contract}, nil } -// bindTypedMemView binds a generic wrapper to an already deployed contract. -func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) +// bindSystemMessage binds a generic wrapper to an already deployed contract. +func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) if err != nil { return nil, err } @@ -5499,191 +7396,169 @@ func bindTypedMemView(address common.Address, caller bind.ContractCaller, transa // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) +func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transfer(opts) +func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transact(opts, method, params...) -} - -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { - var out []interface{} - err := _TypedMemView.contract.Call(opts, &out, "NULL") - - if err != nil { - return *new([29]byte), err - } - - out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - - return out0, err - +func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transact(opts, method, params...) } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) +// TipsMetaData contains all meta data concerning the Tips contract. +var TipsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220925ac4f818c4109946a24ff7cef9ce6373c0521e82f7ff2d0cf8c5d2d771174064736f6c634300080d0033", } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) -} +// TipsABI is the input ABI used to generate the binding from. +// Deprecated: Use TipsMetaData.ABI instead. +var TipsABI = TipsMetaData.ABI -// UpdaterStorageMetaData contains all meta data concerning the UpdaterStorage contract. -var UpdaterStorageMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "8d3638f4": "localDomain()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "b7bc563e": "setSystemMessenger(address)", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "df034cd0": "updater()", - }, -} +// TipsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TipsMetaData.Bin instead. +var TipsBin = TipsMetaData.Bin -// UpdaterStorageABI is the input ABI used to generate the binding from. -// Deprecated: Use UpdaterStorageMetaData.ABI instead. -var UpdaterStorageABI = UpdaterStorageMetaData.ABI +// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. +func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { + parsed, err := TipsMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } -// Deprecated: Use UpdaterStorageMetaData.Sigs instead. -// UpdaterStorageFuncSigs maps the 4-byte function signature to its string representation. -var UpdaterStorageFuncSigs = UpdaterStorageMetaData.Sigs + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil +} -// UpdaterStorage is an auto generated Go binding around an Ethereum contract. -type UpdaterStorage struct { - UpdaterStorageCaller // Read-only binding to the contract - UpdaterStorageTransactor // Write-only binding to the contract - UpdaterStorageFilterer // Log filterer for contract events +// Tips is an auto generated Go binding around an Ethereum contract. +type Tips struct { + TipsCaller // Read-only binding to the contract + TipsTransactor // Write-only binding to the contract + TipsFilterer // Log filterer for contract events } -// UpdaterStorageCaller is an auto generated read-only Go binding around an Ethereum contract. -type UpdaterStorageCaller struct { +// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TipsCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactor struct { +// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TipsTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UpdaterStorageFilterer struct { +// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TipsFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageSession is an auto generated Go binding around an Ethereum contract, +// TipsSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type UpdaterStorageSession struct { - Contract *UpdaterStorage // Generic contract binding to set the session for +type TipsSession struct { + Contract *Tips // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type UpdaterStorageCallerSession struct { - Contract *UpdaterStorageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type TipsCallerSession struct { + Contract *TipsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// UpdaterStorageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type UpdaterStorageTransactorSession struct { - Contract *UpdaterStorageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type TipsTransactorSession struct { + Contract *TipsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageRaw is an auto generated low-level Go binding around an Ethereum contract. -type UpdaterStorageRaw struct { - Contract *UpdaterStorage // Generic contract binding to access the raw methods on +// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TipsRaw struct { + Contract *Tips // Generic contract binding to access the raw methods on } -// UpdaterStorageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UpdaterStorageCallerRaw struct { - Contract *UpdaterStorageCaller // Generic read-only contract binding to access the raw methods on +// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TipsCallerRaw struct { + Contract *TipsCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactorRaw struct { - Contract *UpdaterStorageTransactor // Generic write-only contract binding to access the raw methods on +// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TipsTransactorRaw struct { + Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on } -// NewUpdaterStorage creates a new instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorage(address common.Address, backend bind.ContractBackend) (*UpdaterStorage, error) { - contract, err := bindUpdaterStorage(address, backend, backend, backend) +// NewTips creates a new instance of Tips, bound to a specific deployed contract. +func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { + contract, err := bindTips(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorage{UpdaterStorageCaller: UpdaterStorageCaller{contract: contract}, UpdaterStorageTransactor: UpdaterStorageTransactor{contract: contract}, UpdaterStorageFilterer: UpdaterStorageFilterer{contract: contract}}, nil + return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil } -// NewUpdaterStorageCaller creates a new read-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageCaller(address common.Address, caller bind.ContractCaller) (*UpdaterStorageCaller, error) { - contract, err := bindUpdaterStorage(address, caller, nil, nil) +// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. +func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { + contract, err := bindTips(address, caller, nil, nil) if err != nil { return nil, err } - return &UpdaterStorageCaller{contract: contract}, nil + return &TipsCaller{contract: contract}, nil } -// NewUpdaterStorageTransactor creates a new write-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageTransactor(address common.Address, transactor bind.ContractTransactor) (*UpdaterStorageTransactor, error) { - contract, err := bindUpdaterStorage(address, nil, transactor, nil) +// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. +func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { + contract, err := bindTips(address, nil, transactor, nil) if err != nil { return nil, err } - return &UpdaterStorageTransactor{contract: contract}, nil + return &TipsTransactor{contract: contract}, nil } -// NewUpdaterStorageFilterer creates a new log filterer instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageFilterer(address common.Address, filterer bind.ContractFilterer) (*UpdaterStorageFilterer, error) { - contract, err := bindUpdaterStorage(address, nil, nil, filterer) +// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. +func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { + contract, err := bindTips(address, nil, nil, filterer) if err != nil { return nil, err } - return &UpdaterStorageFilterer{contract: contract}, nil + return &TipsFilterer{contract: contract}, nil } -// bindUpdaterStorage binds a generic wrapper to an already deployed contract. -func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(UpdaterStorageABI)) +// bindTips binds a generic wrapper to an already deployed contract. +func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TipsABI)) if err != nil { return nil, err } @@ -5694,810 +7569,422 @@ func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.UpdaterStorageCaller.contract.Call(opts, result, method, params...) +func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transfer(opts) +func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transact(opts, method, params...) +func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.contract.Call(opts, result, method, params...) +func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transfer(opts) +func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transact(opts, method, params...) -} - -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "localDomain") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - +func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.contract.Transact(opts, method, params...) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) +// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. +var TypeCastsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f937ba1ec907990c38c04e13fdac240c223d1b04b8e825a7cfd351cfe029ae6864736f6c634300080d0033", } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCallerSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) -} +// TypeCastsABI is the input ABI used to generate the binding from. +// Deprecated: Use TypeCastsMetaData.ABI instead. +var TypeCastsABI = TypeCastsMetaData.ABI -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "owner") +// TypeCastsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypeCastsMetaData.Bin instead. +var TypeCastsBin = TypeCastsMetaData.Bin +// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. +func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { + parsed, err := TypeCastsMetaData.GetAbi() if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "systemMessenger") - - if err != nil { - return *new(common.Address), err + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "updater") - + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) + return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "renounceOwnership") +// TypeCasts is an auto generated Go binding around an Ethereum contract. +type TypeCasts struct { + TypeCastsCaller // Read-only binding to the contract + TypeCastsTransactor // Write-only binding to the contract + TypeCastsFilterer // Log filterer for contract events } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) +// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypeCastsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) +// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypeCastsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypeCastsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// TypeCastsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypeCastsSession struct { + Contract *TypeCasts // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypeCastsCallerSession struct { + Contract *TypeCastsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "transferOwnership", newOwner) +// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypeCastsTransactorSession struct { + Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypeCastsRaw struct { + Contract *TypeCasts // Generic contract binding to access the raw methods on } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypeCastsCallerRaw struct { + Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the UpdaterStorage contract. -type UpdaterStorageInitializedIterator struct { - Event *UpdaterStorageInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypeCastsTransactorRaw struct { + Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() +// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { + contract, err := bindTypeCasts(address, backend, backend, backend) + if err != nil { + return nil, err } + return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageInitializedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UpdaterStorageInitialized represents a Initialized event raised by the UpdaterStorage contract. -type UpdaterStorageInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { + contract, err := bindTypeCasts(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TypeCastsCaller{contract: contract}, nil } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterInitialized(opts *bind.FilterOpts) (*UpdaterStorageInitializedIterator, error) { - - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Initialized") +// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { + contract, err := bindTypeCasts(address, nil, transactor, nil) if err != nil { return nil, err } - return &UpdaterStorageInitializedIterator{contract: _UpdaterStorage.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &TypeCastsTransactor{contract: contract}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *UpdaterStorageInitialized) (event.Subscription, error) { - - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Initialized") +// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { + contract, err := bindTypeCasts(address, nil, nil, filterer) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypeCastsFilterer{contract: contract}, nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseInitialized(log types.Log) (*UpdaterStorageInitialized, error) { - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { +// bindTypeCasts binds a generic wrapper to an already deployed contract. +func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// UpdaterStorageNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdaterIterator struct { - Event *UpdaterStorageNewUpdater // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.contract.Call(opts, result, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageNewUpdaterIterator) Error() error { - return it.fail +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transfer(opts) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transact(opts, method, params...) } -// UpdaterStorageNewUpdater represents a NewUpdater event raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. +var TypedMemViewMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "f26be3fc": "NULL()", + }, + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220802d542f548dd16236b5168df2902ecfe93508d03a00eecc215cf533c4eeebad64736f6c634300080d0033", } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*UpdaterStorageNewUpdaterIterator, error) { +// TypedMemViewABI is the input ABI used to generate the binding from. +// Deprecated: Use TypedMemViewMetaData.ABI instead. +var TypedMemViewABI = TypedMemViewMetaData.ABI - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "NewUpdater") - if err != nil { - return nil, err - } - return &UpdaterStorageNewUpdaterIterator{contract: _UpdaterStorage.contract, event: "NewUpdater", logs: logs, sub: sub}, nil -} +// Deprecated: Use TypedMemViewMetaData.Sigs instead. +// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. +var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *UpdaterStorageNewUpdater) (event.Subscription, error) { +// TypedMemViewBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypedMemViewMetaData.Bin instead. +var TypedMemViewBin = TypedMemViewMetaData.Bin - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "NewUpdater") +// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. +func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { + parsed, err := TypedMemViewMetaData.GetAbi() if err != nil { - return nil, err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseNewUpdater(log types.Log) (*UpdaterStorageNewUpdater, error) { - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// TypedMemView is an auto generated Go binding around an Ethereum contract. +type TypedMemView struct { + TypedMemViewCaller // Read-only binding to the contract + TypedMemViewTransactor // Write-only binding to the contract + TypedMemViewFilterer // Log filterer for contract events } -// UpdaterStorageOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferredIterator struct { - Event *UpdaterStorageOwnershipTransferred // Event containing the contract specifics and raw log +// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypedMemViewCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypedMemViewTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypedMemViewFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypedMemViewSession struct { + Contract *TypedMemView // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypedMemViewCallerSession struct { + Contract *TypedMemViewCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypedMemViewTransactorSession struct { + Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageOwnershipTransferredIterator) Error() error { - return it.fail +// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypedMemViewRaw struct { + Contract *TypedMemView // Generic contract binding to access the raw methods on } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil +// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypedMemViewCallerRaw struct { + Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageOwnershipTransferred represents a OwnershipTransferred event raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypedMemViewTransactorRaw struct { + Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UpdaterStorageOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) +// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { + contract, err := bindTypedMemView(address, backend, backend, backend) + if err != nil { + return nil, err } + return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil +} - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { + contract, err := bindTypedMemView(address, caller, nil, nil) if err != nil { return nil, err } - return &UpdaterStorageOwnershipTransferredIterator{contract: _UpdaterStorage.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &TypedMemViewCaller{contract: contract}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UpdaterStorageOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) +// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { + contract, err := bindTypedMemView(address, nil, transactor, nil) + if err != nil { + return nil, err } + return &TypedMemViewTransactor{contract: contract}, nil +} - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { + contract, err := bindTypedMemView(address, nil, nil, filterer) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypedMemViewFilterer{contract: contract}, nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseOwnershipTransferred(log types.Log) (*UpdaterStorageOwnershipTransferred, error) { - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// bindTypedMemView binds a generic wrapper to an already deployed contract. +func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// UpdaterStorageUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the UpdaterStorage contract. -type UpdaterStorageUpdateIterator struct { - Event *UpdaterStorageUpdate // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageUpdateIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageUpdateIterator) Error() error { - return it.fail +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.contract.Call(opts, result, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageUpdateIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transfer(opts) } -// UpdaterStorageUpdate represents a Update event raised by the UpdaterStorage contract. -type UpdaterStorageUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transact(opts, method, params...) } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*UpdaterStorageUpdateIterator, error) { - - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { + var out []interface{} + err := _TypedMemView.contract.Call(opts, &out, "NULL") - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new([29]byte), err } - return &UpdaterStorageUpdateIterator{contract: _UpdaterStorage.contract, event: "Update", logs: logs, sub: sub}, nil -} -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. -// -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *UpdaterStorageUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { + out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } + return out0, err - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { - return err - } - event.Raw = log +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. +// +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseUpdate(log types.Log) (*UpdaterStorageUpdate, error) { - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } // Version0MetaData contains all meta data concerning the Version0 contract. @@ -6506,7 +7993,7 @@ var Version0MetaData = &bind.MetaData{ Sigs: map[string]string{ "ffa1ad74": "VERSION()", }, - Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208c5fb2407775019b157ea125b93a1a55e918940081807b46322c7f52d22e14c264736f6c634300080d0033", + Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220e6b05536f202394e029bd7cf9e31164cadcf895ceb7cb5b417fbb857ee50f3d664736f6c634300080d0033", } // Version0ABI is the input ABI used to generate the binding from. diff --git a/core/contracts/replicamanager/replicamanager.contractinfo.json b/core/contracts/replicamanager/replicamanager.contractinfo.json index 1d65a83ce9..88ecc1630a 100644 --- a/core/contracts/replicamanager/replicamanager.contractinfo.json +++ b/core/contracts/replicamanager/replicamanager.contractinfo.json @@ -1 +1 @@ -{"solidity/ReplicaManager.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204b230d9c26cd1dd9a151d1741f1f6552f668447fd46dcf49d3be4505c7468ad264736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204b230d9c26cd1dd9a151d1741f1f6552f668447fd46dcf49d3be4505c7468ad264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"53465:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;53465:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"53465:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ebcf0879a676dd3fd02954c3a843377d2a33085a237b62601f0f050cc9209cd164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ebcf0879a676dd3fd02954c3a843377d2a33085a237b62601f0f050cc9209cd164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"72965:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;72965:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"72965:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122014bcd9f069378f066068e7d01c733591f31339484b7e3bbd4949dc7a5a76129e64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122014bcd9f069378f066068e7d01c733591f31339484b7e3bbd4949dc7a5a76129e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"76183:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;76183:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"76183:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:AuthManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"AuthManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122014c25ba61171c79b0e1125228a2b266115edc5990fe5f425e4df2e44aed43d8864736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122014c25ba61171c79b0e1125228a2b266115edc5990fe5f425e4df2e44aed43d8864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44399:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;44399:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"44399:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122026e0c7d056e7f2e1ee28e6b78f5c05e06568f5bc13bbca2169f0138f08a4256764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122026e0c7d056e7f2e1ee28e6b78f5c05e06568f5bc13bbca2169f0138f08a4256764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"39115:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;39115:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"39115:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:IMessageRecipient":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_origin","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint256","name":"_rootTimestamp","type":"uint256"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"handle","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_rootTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"handle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"IMessageRecipient\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{"handle(uint32,uint32,bytes32,uint256,bytes)":"e4d16d62"}},"solidity/ReplicaManager.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/ReplicaManager.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208c25107868cbe1e9cbeeebef277d92e469db47e01c3a51a6f1455e28acab727464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208c25107868cbe1e9cbeeebef277d92e469db47e01c3a51a6f1455e28acab727464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"83496:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;83496:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"83496:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f424867ec96f6ba6ac980b7c42915bd0afc154d6ffcf0fdb0d83c6cf60b3c5a264736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f424867ec96f6ba6ac980b7c42915bd0afc154d6ffcf0fdb0d83c6cf60b3c5a264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"34142:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;34142:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"34142:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManager.sol:ReplicaLib":{"code":"0x6098610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea2646970667358221220b5521aa205eb54c917cf81b4f1c79b19818b68fef0fb5d39ccbdd943c15a444964736f6c634300080d0033","runtime-code":"0x7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea2646970667358221220b5521aa205eb54c917cf81b4f1c79b19818b68fef0fb5d39ccbdd943c15a444964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80495:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;80495:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"80495:2999:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81564:70;;81631:1;81564:70;;;;;168:25:1;;;156:2;141:18;81564:70:0;;;;;;;81502:56;;81556:1;81502:56;","abiDefinition":[{"inputs":[],"name":"MESSAGE_STATUS_NONE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_STATUS_PROCESSED","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"MESSAGE_STATUS_NONE":{"details":"Should not be possible to have 0x0 or 0x1 as valid Merkle root, so it's safe to use those values as NONE/PROCESSED"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"MESSAGE_STATUS_NONE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MESSAGE_STATUS_PROCESSED\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"MESSAGE_STATUS_NONE\":{\"details\":\"Should not be possible to have 0x0 or 0x1 as valid Merkle root, so it's safe to use those values as NONE/PROCESSED\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ReplicaLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{"MESSAGE_STATUS_NONE()":"b0075818","MESSAGE_STATUS_PROCESSED()":"643d8086"}},"solidity/ReplicaManager.sol:ReplicaManager":{"code":"0x60a06040523480156200001157600080fd5b5060405162002dbc38038062002dbc833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612d206200009c60003960008181610256015281816108470152610eb80152612d206000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c8063928bc4b2116100cd578063ccbdf9c911610081578063f2fde38b11610066578063f2fde38b1461038e578063f646a512146103a1578063ffa1ad74146103b457600080fd5b8063ccbdf9c91461034e578063df034cd01461036e57600080fd5b80639df7d36d116100b25780639df7d36d146102f2578063b65672d314610305578063b7bc563e1461033b57600080fd5b8063928bc4b2146102cc5780639d54f419146102df57600080fd5b8063715018a6116101245780638624c35c116101095780638624c35c1461023e5780638d3638f4146102515780638da5cb5b1461028d57600080fd5b8063715018a6146101f55780637dfdba28146101fd57600080fd5b806315a046aa146101565780634f63be3f1461017e578063634155141461019157806368705275146101e0575b600080fd5b610169610164366004612701565b6103ce565b60405190151581526020015b60405180910390f35b61016961018c366004612817565b61042b565b6101d261019f366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b604051908152602001610175565b6101f36101ee366004612817565b6105a5565b005b6101f361060c565b6101d261020b366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101f361024c3660046128d3565b610675565b6102787f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6101f36102da36600461290a565b6107ee565b6101f36102ed36600461293f565b610b8a565b6101f361030036600461295c565b610bfa565b61027861031336600461298f565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101f361034936600461293f565b610cee565b6066546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6101f361039c36600461293f565b610d9c565b6101f36103af36600461290a565b610e95565b6103bc600081565b60405160ff9091168152602001610175565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361040d576000915050610424565b61041d63ffffffff8516826129d9565b4210159150505b9392505050565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff16600281111561047a5761047a6129f1565b146104cc5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561052a5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016104c3565b60006105608387602080602002604051908101604052809291908260208002808284376000920191909152508991506110709050565b60008181526001840160205260409020549091501561059557600092835260029190910160205260409091205550600161059d565b600093505050505b949350505050565b6105b18484848461042b565b6105fd5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016104c3565b610606836107ee565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106735760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b565b60006106816001611116565b905080156106b657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6106bf8261126d565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107708360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc602052604090205580156107e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006107f9826112f2565b9050600061080c62ffffff198316611306565b9050600061081f62ffffff198316611346565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661087662ffffff198516611370565b63ffffffff16146108c95760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016104c3565b60006108da62ffffff198616611391565b60008181526002840160205260409020549091506108f7816113ee565b6109435760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016104c3565b61095c8461095662ffffff198816611402565b836103ce565b6109a85760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016104c3565b60c95460ff166001146109fd5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016104c3565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610a3a610a3762ffffff198816611423565b50565b6000828152600284016020526040812060019055610a65610a6062ffffff19881661145a565b61147b565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610a9362ffffff198a166114bd565b610aa262ffffff198b166114de565b600087815260018a016020526040902054610ad0610ac562ffffff198f166114ff565b62ffffff191661153e565b6040518663ffffffff1660e01b8152600401610af0959493929190612a8b565b600060405180830381600087803b158015610b0a57600080fd5b505af1158015610b1e573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bf15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b610a3781611591565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610ca49083908690869061161716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d555760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b73ffffffffffffffffffffffffffffffffffffffff8116610e8c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104c3565b610a378161162b565b6000610ea0826116a2565b9150506000610eb48262ffffff19166117c3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610f315760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016104c3565b6000610f4262ffffff1984166117d7565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020805492935091811690831611610fbd5760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016104c3565b6000610fce62ffffff1986166117eb565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171611053610ac58a62ffffff1916611800565b6040516110609190612acb565b60405180910390a4505050505050565b8260005b602081101561110e57600183821c16600085836020811061109757611097612ade565b60200201519050816001036110d7576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611104565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611074565b509392505050565b60008054610100900460ff16156111b3578160ff1660011480156111395750303b155b6111ab5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b506000919050565b60005460ff8084169116106112305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166112ea5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610bf1611833565b6000611300826105396118b8565b92915050565b60008161131b62ffffff1982166105396118dc565b5061133d8361132b8560016119dd565b6113368660026119dd565b6001611a0f565b91505b50919050565b60008161135c60015b62ffffff198316906118dc565b5061133d62ffffff19841660026004611a2e565b60008161137d600161134f565b5061133d62ffffff198416602a6004611a2e565b6000806113ac8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006113d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906113005750506001141590565b60008161140f600161134f565b5061133d62ffffff198416604e6004611a2e565b60008161143862ffffff1982166105396118dc565b5061133d836114488560026119dd565b6114538660036119dd565b6002611a0f565b600081611467600161134f565b5061133d62ffffff198416602e6020611a5e565b60007401000000000000000000000000000000000000000082016114b757505060665473ffffffffffffffffffffffffffffffffffffffff1690565b81611300565b6000816114ca600161134f565b5061133d62ffffff19841660266004611a2e565b6000816114eb600161134f565b5061133d62ffffff19841660066020611a5e565b60008161151462ffffff1982166105396118dc565b5061133d836115248560036119dd565b601886901c6bffffffffffffffffffffffff166003611a0f565b606060008061155b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506115808483602001611c1c565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806116af83826118b8565b905060286bffffffffffffffffffffffff601883901c16116117135760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016104c3565b61173c61172562ffffff198316611dc1565b611737610ac562ffffff198516611800565b611dd6565b915061177261175062ffffff1983166117c3565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6117be5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e2075706461746572000000000000000060448201526064016104c3565b915091565b600061130062ffffff198316826004611a2e565b600061130062ffffff198316600480611a2e565b600061130062ffffff19831660086020611a5e565b6000611300602861182381601886901c6bffffffffffffffffffffffff16612b0d565b62ffffff19851691906000611e4d565b600054610100900460ff166118b05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610673611ec7565b8151600090602084016118d364ffffffffff85168284611f4d565b95945050505050565b60006118e88383611f94565b6119d65760006119076118fb8560d81c90565b64ffffffffff16611fb7565b915050600061191c8464ffffffffff16611fb7565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016104c39190612acb565b5090919050565b600061042460028360048111156119f6576119f66129f1565b611a009190612b24565b62ffffff198516906002611a2e565b60006118d384611a1f8186612b0d565b62ffffff198816919085611e4d565b6000611a3b826020612b61565b611a46906008612b84565b60ff16611a54858585611a5e565b901c949350505050565b60008160ff16600003611a7357506000610424565b611a8b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aa660ff8416856129d9565b1115611b1e57611b05611ac78560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aed8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166120a1565b60405162461bcd60e51b81526004016104c39190612acb565b60208260ff161115611b985760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104c3565b600882026000611bb68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611c995760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016104c3565b611ca28361210f565b611d145760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016104c3565b6000611d2e8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611d588560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611d7d5760206060fd5b8285848460045afa50611db7611d938760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061130062ffffff19831682602881611e4d565b600080611de862ffffff198516611391565b9050611e41816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061059d818461214c565b600080611e688660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050611e8186612168565b84611e8c87846129d9565b611e9691906129d9565b1115611ea95762ffffff1991505061059d565b611eb385826129d9565b9050611db78364ffffffffff168286611f4d565b600054610100900460ff16611f445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b6106733361162b565b600080611f5a83856129d9565b9050604051811115611f6a575060005b80600003611f7f5762ffffff19915050610424565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16611fa88460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561202a576000611fd6826008612b84565b60ff1685901c9050611fe7816121b0565b61ffff16841793508160ff1660101461200257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611fbd565b50600f5b60ff8160ff16101561209b576000612047826008612b84565b60ff1685901c9050612058816121b0565b61ffff16831792508160ff1660001461207357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161202e565b50915091565b606060006120ae86611fb7565b91505060006120bc86611fb7565b91505060006120ca86611fb7565b91505060006120d886611fb7565b915050838383836040516020016120f29493929190612bad565b604051602081830303815290604052945050505050949350505050565b600061211b8260d81c90565b64ffffffffff1664ffffffffff0361213557506000919050565b600061214083612168565b60405110199392505050565b600080600061215b85856121e2565b9150915061110e81612250565b60006121828260181c6bffffffffffffffffffffffff1690565b61219a8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006121c260048360ff16901c61243c565b60ff1661ffff919091161760081b6121d98261243c565b60ff1617919050565b60008082516041036122185760208301516040840151606085015160001a61220c87828585612583565b94509450505050612249565b8251604003612241576020830151604084015161223686838361269b565b935093505050612249565b506000905060025b9250929050565b6000816004811115612264576122646129f1565b0361226c5750565b6001816004811115612280576122806129f1565b036122cd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104c3565b60028160048111156122e1576122e16129f1565b0361232e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104c3565b6003816004811115612342576123426129f1565b036123b55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b60048160048111156123c9576123c96129f1565b03610a375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b600060f08083179060ff821690036124575750603092915050565b8060ff1660f10361246b5750603192915050565b8060ff1660f20361247f5750603292915050565b8060ff1660f3036124935750603392915050565b8060ff1660f4036124a75750603492915050565b8060ff1660f5036124bb5750603592915050565b8060ff1660f6036124cf5750603692915050565b8060ff1660f7036124e35750603792915050565b8060ff1660f8036124f75750603892915050565b8060ff1660f90361250b5750603992915050565b8060ff1660fa0361251f5750606192915050565b8060ff1660fb036125335750606292915050565b8060ff1660fc036125475750606392915050565b8060ff1660fd0361255b5750606492915050565b8060ff1660fe0361256f5750606592915050565b8060ff1660ff036113405750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156125ba5750600090506003612692565b8460ff16601b141580156125d257508460ff16601c14155b156125e35750600090506004612692565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612637573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661268b57600060019250925050612692565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816126d160ff86901c601b6129d9565b90506126df87828885612583565b935093505050935093915050565b803563ffffffff8116811461126857600080fd5b60008060006060848603121561271657600080fd5b61271f846126ed565b925061272d602085016126ed565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261277d57600080fd5b813567ffffffffffffffff808211156127985761279861273d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156127de576127de61273d565b816040528381528660208588010111156127f757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561282e57600080fd5b612837856126ed565b9350602085013567ffffffffffffffff81111561285357600080fd5b61285f8782880161276c565b93505061044085018681111561287457600080fd5b9396929550505060409290920191903590565b6000806040838503121561289a57600080fd5b6128a3836126ed565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a3757600080fd5b600080604083850312156128e657600080fd5b6128ef836126ed565b915060208301356128ff816128b1565b809150509250929050565b60006020828403121561291c57600080fd5b813567ffffffffffffffff81111561293357600080fd5b61059d8482850161276c565b60006020828403121561295157600080fd5b8135610424816128b1565b60008060006060848603121561297157600080fd5b61297a846126ed565b95602085013595506040909401359392505050565b6000602082840312156129a157600080fd5b610424826126ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156129ec576129ec6129aa565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612a4657602081850181015186830182015201612a2a565b81811115612a58576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612ac060a0830184612a20565b979650505050505050565b6020815260006104246020830184612a20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612b1f57612b1f6129aa565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b5c57612b5c6129aa565b500290565b600060ff821660ff841680821015612b7b57612b7b6129aa565b90039392505050565b600060ff821660ff84168160ff0481118215151615612ba557612ba56129aa565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611db756fea2646970667358221220c2d6abd028a1cb35e1537efe976dc2970cbb4dbe911ca61808e63125c173e4c964736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106101515760003560e01c8063928bc4b2116100cd578063ccbdf9c911610081578063f2fde38b11610066578063f2fde38b1461038e578063f646a512146103a1578063ffa1ad74146103b457600080fd5b8063ccbdf9c91461034e578063df034cd01461036e57600080fd5b80639df7d36d116100b25780639df7d36d146102f2578063b65672d314610305578063b7bc563e1461033b57600080fd5b8063928bc4b2146102cc5780639d54f419146102df57600080fd5b8063715018a6116101245780638624c35c116101095780638624c35c1461023e5780638d3638f4146102515780638da5cb5b1461028d57600080fd5b8063715018a6146101f55780637dfdba28146101fd57600080fd5b806315a046aa146101565780634f63be3f1461017e578063634155141461019157806368705275146101e0575b600080fd5b610169610164366004612701565b6103ce565b60405190151581526020015b60405180910390f35b61016961018c366004612817565b61042b565b6101d261019f366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b604051908152602001610175565b6101f36101ee366004612817565b6105a5565b005b6101f361060c565b6101d261020b366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101f361024c3660046128d3565b610675565b6102787f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6101f36102da36600461290a565b6107ee565b6101f36102ed36600461293f565b610b8a565b6101f361030036600461295c565b610bfa565b61027861031336600461298f565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101f361034936600461293f565b610cee565b6066546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6101f361039c36600461293f565b610d9c565b6101f36103af36600461290a565b610e95565b6103bc600081565b60405160ff9091168152602001610175565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361040d576000915050610424565b61041d63ffffffff8516826129d9565b4210159150505b9392505050565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff16600281111561047a5761047a6129f1565b146104cc5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561052a5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016104c3565b60006105608387602080602002604051908101604052809291908260208002808284376000920191909152508991506110709050565b60008181526001840160205260409020549091501561059557600092835260029190910160205260409091205550600161059d565b600093505050505b949350505050565b6105b18484848461042b565b6105fd5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016104c3565b610606836107ee565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106735760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b565b60006106816001611116565b905080156106b657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6106bf8261126d565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107708360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc602052604090205580156107e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006107f9826112f2565b9050600061080c62ffffff198316611306565b9050600061081f62ffffff198316611346565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661087662ffffff198516611370565b63ffffffff16146108c95760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016104c3565b60006108da62ffffff198616611391565b60008181526002840160205260409020549091506108f7816113ee565b6109435760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016104c3565b61095c8461095662ffffff198816611402565b836103ce565b6109a85760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016104c3565b60c95460ff166001146109fd5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016104c3565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610a3a610a3762ffffff198816611423565b50565b6000828152600284016020526040812060019055610a65610a6062ffffff19881661145a565b61147b565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610a9362ffffff198a166114bd565b610aa262ffffff198b166114de565b600087815260018a016020526040902054610ad0610ac562ffffff198f166114ff565b62ffffff191661153e565b6040518663ffffffff1660e01b8152600401610af0959493929190612a8b565b600060405180830381600087803b158015610b0a57600080fd5b505af1158015610b1e573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bf15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b610a3781611591565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610ca49083908690869061161716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d555760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b73ffffffffffffffffffffffffffffffffffffffff8116610e8c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104c3565b610a378161162b565b6000610ea0826116a2565b9150506000610eb48262ffffff19166117c3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610f315760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016104c3565b6000610f4262ffffff1984166117d7565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020805492935091811690831611610fbd5760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016104c3565b6000610fce62ffffff1986166117eb565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171611053610ac58a62ffffff1916611800565b6040516110609190612acb565b60405180910390a4505050505050565b8260005b602081101561110e57600183821c16600085836020811061109757611097612ade565b60200201519050816001036110d7576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611104565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611074565b509392505050565b60008054610100900460ff16156111b3578160ff1660011480156111395750303b155b6111ab5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b506000919050565b60005460ff8084169116106112305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166112ea5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610bf1611833565b6000611300826105396118b8565b92915050565b60008161131b62ffffff1982166105396118dc565b5061133d8361132b8560016119dd565b6113368660026119dd565b6001611a0f565b91505b50919050565b60008161135c60015b62ffffff198316906118dc565b5061133d62ffffff19841660026004611a2e565b60008161137d600161134f565b5061133d62ffffff198416602a6004611a2e565b6000806113ac8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006113d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906113005750506001141590565b60008161140f600161134f565b5061133d62ffffff198416604e6004611a2e565b60008161143862ffffff1982166105396118dc565b5061133d836114488560026119dd565b6114538660036119dd565b6002611a0f565b600081611467600161134f565b5061133d62ffffff198416602e6020611a5e565b60007401000000000000000000000000000000000000000082016114b757505060665473ffffffffffffffffffffffffffffffffffffffff1690565b81611300565b6000816114ca600161134f565b5061133d62ffffff19841660266004611a2e565b6000816114eb600161134f565b5061133d62ffffff19841660066020611a5e565b60008161151462ffffff1982166105396118dc565b5061133d836115248560036119dd565b601886901c6bffffffffffffffffffffffff166003611a0f565b606060008061155b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506115808483602001611c1c565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806116af83826118b8565b905060286bffffffffffffffffffffffff601883901c16116117135760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016104c3565b61173c61172562ffffff198316611dc1565b611737610ac562ffffff198516611800565b611dd6565b915061177261175062ffffff1983166117c3565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6117be5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e2075706461746572000000000000000060448201526064016104c3565b915091565b600061130062ffffff198316826004611a2e565b600061130062ffffff198316600480611a2e565b600061130062ffffff19831660086020611a5e565b6000611300602861182381601886901c6bffffffffffffffffffffffff16612b0d565b62ffffff19851691906000611e4d565b600054610100900460ff166118b05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610673611ec7565b8151600090602084016118d364ffffffffff85168284611f4d565b95945050505050565b60006118e88383611f94565b6119d65760006119076118fb8560d81c90565b64ffffffffff16611fb7565b915050600061191c8464ffffffffff16611fb7565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016104c39190612acb565b5090919050565b600061042460028360048111156119f6576119f66129f1565b611a009190612b24565b62ffffff198516906002611a2e565b60006118d384611a1f8186612b0d565b62ffffff198816919085611e4d565b6000611a3b826020612b61565b611a46906008612b84565b60ff16611a54858585611a5e565b901c949350505050565b60008160ff16600003611a7357506000610424565b611a8b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aa660ff8416856129d9565b1115611b1e57611b05611ac78560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aed8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166120a1565b60405162461bcd60e51b81526004016104c39190612acb565b60208260ff161115611b985760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104c3565b600882026000611bb68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611c995760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016104c3565b611ca28361210f565b611d145760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016104c3565b6000611d2e8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611d588560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611d7d5760206060fd5b8285848460045afa50611db7611d938760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061130062ffffff19831682602881611e4d565b600080611de862ffffff198516611391565b9050611e41816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061059d818461214c565b600080611e688660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050611e8186612168565b84611e8c87846129d9565b611e9691906129d9565b1115611ea95762ffffff1991505061059d565b611eb385826129d9565b9050611db78364ffffffffff168286611f4d565b600054610100900460ff16611f445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b6106733361162b565b600080611f5a83856129d9565b9050604051811115611f6a575060005b80600003611f7f5762ffffff19915050610424565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16611fa88460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561202a576000611fd6826008612b84565b60ff1685901c9050611fe7816121b0565b61ffff16841793508160ff1660101461200257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611fbd565b50600f5b60ff8160ff16101561209b576000612047826008612b84565b60ff1685901c9050612058816121b0565b61ffff16831792508160ff1660001461207357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161202e565b50915091565b606060006120ae86611fb7565b91505060006120bc86611fb7565b91505060006120ca86611fb7565b91505060006120d886611fb7565b915050838383836040516020016120f29493929190612bad565b604051602081830303815290604052945050505050949350505050565b600061211b8260d81c90565b64ffffffffff1664ffffffffff0361213557506000919050565b600061214083612168565b60405110199392505050565b600080600061215b85856121e2565b9150915061110e81612250565b60006121828260181c6bffffffffffffffffffffffff1690565b61219a8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006121c260048360ff16901c61243c565b60ff1661ffff919091161760081b6121d98261243c565b60ff1617919050565b60008082516041036122185760208301516040840151606085015160001a61220c87828585612583565b94509450505050612249565b8251604003612241576020830151604084015161223686838361269b565b935093505050612249565b506000905060025b9250929050565b6000816004811115612264576122646129f1565b0361226c5750565b6001816004811115612280576122806129f1565b036122cd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104c3565b60028160048111156122e1576122e16129f1565b0361232e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104c3565b6003816004811115612342576123426129f1565b036123b55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b60048160048111156123c9576123c96129f1565b03610a375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b600060f08083179060ff821690036124575750603092915050565b8060ff1660f10361246b5750603192915050565b8060ff1660f20361247f5750603292915050565b8060ff1660f3036124935750603392915050565b8060ff1660f4036124a75750603492915050565b8060ff1660f5036124bb5750603592915050565b8060ff1660f6036124cf5750603692915050565b8060ff1660f7036124e35750603792915050565b8060ff1660f8036124f75750603892915050565b8060ff1660f90361250b5750603992915050565b8060ff1660fa0361251f5750606192915050565b8060ff1660fb036125335750606292915050565b8060ff1660fc036125475750606392915050565b8060ff1660fd0361255b5750606492915050565b8060ff1660fe0361256f5750606592915050565b8060ff1660ff036113405750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156125ba5750600090506003612692565b8460ff16601b141580156125d257508460ff16601c14155b156125e35750600090506004612692565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612637573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661268b57600060019250925050612692565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816126d160ff86901c601b6129d9565b90506126df87828885612583565b935093505050935093915050565b803563ffffffff8116811461126857600080fd5b60008060006060848603121561271657600080fd5b61271f846126ed565b925061272d602085016126ed565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261277d57600080fd5b813567ffffffffffffffff808211156127985761279861273d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156127de576127de61273d565b816040528381528660208588010111156127f757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561282e57600080fd5b612837856126ed565b9350602085013567ffffffffffffffff81111561285357600080fd5b61285f8782880161276c565b93505061044085018681111561287457600080fd5b9396929550505060409290920191903590565b6000806040838503121561289a57600080fd5b6128a3836126ed565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a3757600080fd5b600080604083850312156128e657600080fd5b6128ef836126ed565b915060208301356128ff816128b1565b809150509250929050565b60006020828403121561291c57600080fd5b813567ffffffffffffffff81111561293357600080fd5b61059d8482850161276c565b60006020828403121561295157600080fd5b8135610424816128b1565b60008060006060848603121561297157600080fd5b61297a846126ed565b95602085013595506040909401359392505050565b6000602082840312156129a157600080fd5b610424826126ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156129ec576129ec6129aa565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612a4657602081850181015186830182015201612a2a565b81811115612a58576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612ac060a0830184612a20565b979650505050505050565b6020815260006104246020830184612a20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612b1f57612b1f6129aa565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b5c57612b5c6129aa565b500290565b600060ff821660ff841680821015612b7b57612b7b6129aa565b90039392505050565b600060ff821660ff84168160ff0481118215151615612ba557612ba56129aa565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611db756fea2646970667358221220c2d6abd028a1cb35e1537efe976dc2970cbb4dbe911ca61808e63125c173e4c964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"99168:12604:0:-:0;;;100984:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71526:26;;;;99168:12604;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;99168:12604:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"99168:12604:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107800:361;;;;;;:::i;:::-;;:::i;:::-;;;676:14:1;;669:22;651:41;;639:2;624:18;107800:361:0;;;;;;;;108823:1028;;;;;;:::i;:::-;;:::i;102247:230::-;;;;;;:::i;:::-;102414:29;;;;;102372:7;102414:29;;;:14;:29;;;;;;;;;102402:42;;:11;:42;;;;;:68;;;:56;;;;:68;;;;;102247:230;;;;2691:25:1;;;2679:2;2664:18;102247:230:0;2545:177:1;104149:271:0;;;;;;:::i;:::-;;:::i;:::-;;72877:84;;;:::i;102027:214::-;;;;;;:::i;:::-;102187:29;;;;;102145:7;102187:29;;;:14;:29;;;;;;;;;102175:42;;:11;:42;;;;;:59;;;:52;;;;:59;;;;;102027:214;101552:255;;;;;;:::i;:::-;;:::i;70324:35::-;;;;;;;;3566:10:1;3554:23;;;3536:42;;3524:2;3509:18;70324:35:0;3392:192:1;68421:85:0;68493:6;;;;68421:85;;;3765:42:1;3753:55;;;3735:74;;3723:2;3708:18;68421:85:0;3589:226:1;104858:1415:0;;;;;;:::i;:::-;;:::i;106564:95::-;;;;;;:::i;:::-;;:::i;107010:423::-;;;;;;:::i;:::-;;:::i;101868:153::-;;;;;;:::i;:::-;101978:29;;;;101941:6;101978:29;;;:14;:29;;;;;;;;;101966:42;;:11;:42;;;;;:48;;;101868:153;72075:133;;;;;;:::i;:::-;;:::i;70479:39::-;;;;;;;;;70450:22;;;;;;;;;69303:198;;;;;;:::i;:::-;;:::i;102967:731::-;;;;;;:::i;:::-;;:::i;80457:33::-;;80489:1;80457:33;;;;;5612:4:1;5600:17;;;5582:36;;5570:2;5555:18;80457:33:0;5440:184:1;107800:361:0;107983:29;;;107939:4;107983:29;;;:14;:29;;;;;;;;;107971:42;;:11;:42;;;;;:59;;;:52;;:59;;;;;;108044:10;;;108040:53;;108077:5;108070:12;;;;;108040:53;108128:26;;;;:5;:26;:::i;:::-;108109:15;:45;;108102:52;;;107800:361;;;;;;:::o;108823:1028::-;109014:19;;;;;;;;;;109092:29;;;108982:4;109092:29;;;:14;:29;;;;;;;109080:42;;:11;:42;;;;;;109199:31;109181:14;;;;;;;:49;;;;;;;;:::i;:::-;;109173:80;;;;-1:-1:-1;;;109173:80:0;;6342:2:1;109173:80:0;;;6324:21:1;6381:2;6361:18;;;6354:30;6420:20;6400:18;;;6393:48;6458:18;;109173:80:0;;;;;;;;;81556:1;109348:28;;;:21;;;:28;;;;;;:62;109327:128;;;;-1:-1:-1;;;109327:128:0;;6689:2:1;109327:128:0;;;6671:21:1;6728:2;6708:18;;;6701:30;6767:21;6747:18;;;6740:49;6806:18;;109327:128:0;6487:343:1;109327:128:0;109523:23;109549:43;109570:5;109577:6;109549:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109585:6:0;;-1:-1:-1;109549:20:0;;-1:-1:-1;109549:43:0:i;:::-;109684:34;;;;:17;;;:34;;;;;;109523:69;;-1:-1:-1;109684:39:0;109680:143;;83129:35;;;;:21;;;;;:35;;;;;;:45;-1:-1:-1;109808:4:0;109801:11;;109680:143;109839:5;109832:12;;;;;108823:1028;;;;;;;:::o;104149:271::-;104329:46;104335:13;104350:8;104360:6;104368;104329:5;:46::i;:::-;104321:65;;;;-1:-1:-1;;;104321:65:0;;7037:2:1;104321:65:0;;;7019:21:1;7076:1;7056:18;;;7049:29;7114:8;7094:18;;;7087:36;7140:18;;104321:65:0;6835:329:1;104321:65:0;104396:17;104404:8;104396:7;:17::i;:::-;104149:271;;;;:::o;72877:84::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;72877:84::o;101552:255::-;61317:19;61339:25;61362:1;61339:22;:25::i;:::-;61317:47;;61378:14;61374:65;;;61408:13;:20;;;;;;;;61374:65;101641:34:::1;101666:8;101641:24;:34::i;:::-;101718:7;:11:::0;;;::::1;101728:1;101718:11;::::0;;101771:29:::1;101786:13:::0;110140:12;;110155:1;110140:16;109974:20;110176:25;;;:11;:25;;;;;82601:36;;;;;;;82647:37;;;;;;;;;;;110239:12;:27;;;110254:12;109910:363;-1:-1:-1;109910:363:0;101771:29:::1;101739;::::0;::::1;;::::0;;;:14:::1;:29;::::0;;;;:61;61459:99;;;;61509:5;61493:21;;;;;;61533:14;;-1:-1:-1;5582:36:1;;61533:14:0;;5570:2:1;5555:18;61533:14:0;;;;;;;61459:99;61307:257;101552:255;;:::o;104858:1415::-;104915:10;104928:22;:8;:20;:22::i;:::-;104915:35;-1:-1:-1;104960:15:0;104978:11;-1:-1:-1;;104978:9:0;;;:11::i;:::-;104960:29;-1:-1:-1;104999:20:0;105022:16;-1:-1:-1;;105022:14:0;;;:16::i;:::-;105097:29;;;;105048:34;105097:29;;;:14;:29;;;;;;;;;105085:42;;:11;:42;;;;;104999:39;;-1:-1:-1;105222:11:0;105197:36;:21;-1:-1:-1;;105197:19:0;;;:21::i;:::-;:36;;;105189:61;;;;-1:-1:-1;;;105189:61:0;;7931:2:1;105189:61:0;;;7913:21:1;7970:2;7950:18;;;7943:30;8009:14;7989:18;;;7982:42;8041:18;;105189:61:0;7729:336:1;105189:61:0;105302:20;105325:11;-1:-1:-1;;105325:9:0;;;:11::i;:::-;105346:13;105362:35;;;:21;;;:35;;;;;;105302:34;;-1:-1:-1;105415:33:0;105362:35;105415:26;:33::i;:::-;105407:66;;;;-1:-1:-1;;;105407:66:0;;8272:2:1;105407:66:0;;;8254:21:1;8311:2;8291:18;;;8284:30;8350:22;8330:18;;;8323:50;8390:18;;105407:66:0;8070:344:1;105407:66:0;105504:65;105519:13;105534:27;-1:-1:-1;;105534:25:0;;;:27::i;:::-;105563:5;105504:14;:65::i;:::-;105483:130;;;;-1:-1:-1;;;105483:130:0;;8621:2:1;105483:130:0;;;8603:21:1;8660:2;8640:18;;;8633:30;8699:20;8679:18;;;8672:48;8737:18;;105483:130:0;8419:342:1;105483:130:0;105666:7;;;;;:12;105658:35;;;;-1:-1:-1;;;105658:35:0;;8968:2:1;105658:35:0;;;8950:21:1;9007:2;8987:18;;;8980:30;9046:12;9026:18;;;9019:40;9076:18;;105658:35:0;8766:334:1;105658:35:0;105703:7;:11;;;;;;105724:21;105735:9;-1:-1:-1;;105735:7:0;;;:9::i;:::-;106564:95;;105724:21;83129:35;;;;:21;;;:35;;;;;81631:1;83129:45;;105906:43;105929:19;-1:-1:-1;;105929:17:0;;;:19::i;:::-;105906:22;:43::i;:::-;105886:63;-1:-1:-1;105959:35:0;;;;106008:13;106035:15;-1:-1:-1;;106035:13:0;;;:15::i;:::-;106064:16;-1:-1:-1;;106064:14:0;;;:16::i;:::-;106094:24;;;;:17;;;:24;;;;;;106132:17;:9;-1:-1:-1;;106132:7:0;;;:9::i;:::-;-1:-1:-1;;106132:15:0;;:17::i;:::-;105959:200;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;106174:36:0;;106197:12;;-1:-1:-1;106174:36:0;;;;-1:-1:-1;106174:36:0;;;;;-1:-1:-1;;106255:7:0;:11;;;;106265:1;106255:11;;;-1:-1:-1;;;;;;104858:1415:0:o;106564:95::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;106631:21:::1;106643:8;106631:11;:21::i;107010:423::-:0;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;107200:29:::1;::::0;;::::1;107151:34;107200:29:::0;;;:14:::1;:29;::::0;;;;;;;;107188:42;;:11:::1;:42:::0;;;;;107269:24;;;:17:::1;::::0;::::1;:24:::0;;;;;;;107188:42;;107303:39:::1;::::0;107188:42;;107287:5;;107331:10;;107303:20:::1;:39;:::i;:::-;107357:69;::::0;;10366:25:1;;;10422:2;10407:18;;10400:34;;;107388:5:0;;107357:69:::1;::::0;::::1;::::0;::::1;::::0;10339:18:1;107357:69:0::1;;;;;;;107141:292;;107010:423:::0;;;:::o;72075:133::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;72167:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;72075:133::o;69303:198::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;69391:22:::1;::::0;::::1;69383:73;;;::::0;-1:-1:-1;;;69383:73:0;;10647:2:1;69383:73:0::1;::::0;::::1;10629:21:1::0;10686:2;10666:18;;;10659:30;10725:34;10705:18;;;10698:62;10796:8;10776:18;;;10769:36;10822:19;;69383:73:0::1;10445:402:1::0;69383:73:0::1;69466:28;69485:8;69466:18;:28::i;102967:731::-:0;103043:13;103060:31;103078:12;103060:17;:31::i;:::-;103040:51;;;103101:19;103123:25;:5;:23;;;;:25::i;:::-;103101:47;;103182:11;103166:27;;:12;:27;;;103158:68;;;;-1:-1:-1;;;103158:68:0;;11054:2:1;103158:68:0;;;11036:21:1;11093:2;11073:18;;;11066:30;11132;11112:18;;;11105:58;11180:18;;103158:68:0;10852:352:1;103158:68:0;103236:12;103251:24;-1:-1:-1;;103251:22:0;;;:24::i;:::-;103334:28;;;;103285:34;103334:28;;;:14;:28;;;;;;;;;103322:41;;:11;:41;;;;;103389:13;;103236:39;;-1:-1:-1;103322:41:0;103389:13;;103381:21;;;;103373:65;;;;-1:-1:-1;;;103373:65:0;;11411:2:1;103373:65:0;;;11393:21:1;11450:2;11430:18;;;11423:30;11489:33;11469:18;;;11462:61;11540:18;;103373:65:0;11209:355:1;103373:65:0;103448:15;103466:23;-1:-1:-1;;103466:21:0;;;:23::i;:::-;82940:24;;;;:17;;;:24;;;;;103529:15;82940:37;;103448:41;-1:-1:-1;82774:22:0;;;;;;;;;;103645:7;103638:5;103617:74;;103624:12;103617:74;;;103654:36;:28;:5;:26;;;;:28::i;:36::-;103617:74;;;;;;:::i;:::-;;;;;;;;103030:668;;;;;102967:731;:::o;87166:614::-;87345:5;87306:16;87361:413;83559:2;87381:1;:14;87361:413;;;87447:4;87432:11;;;87431:20;87413:15;87481:7;87442:1;87481:10;;;;;;;:::i;:::-;;;;;87465:26;;87509:7;87520:1;87509:12;87505:200;;87562:33;;;;;;12137:19:1;;;12172:12;;;12165:28;;;12209:12;;87562:33:0;;;;;;;;;;;;87552:44;;;;;;87541:55;;87505:200;;;87656:33;;;;;;12137:19:1;;;12172:12;;;12165:28;;;12209:12;;87656:33:0;;;;;;;;;;;;87646:44;;;;;;87635:55;;87505:200;-1:-1:-1;;87746:3:0;;87361:413;;;;87166:614;;;;;:::o;63493:808::-;63557:4;63890:13;;;;;;;63886:409;;;63944:7;:12;;63955:1;63944:12;:61;;;;-1:-1:-1;63999:4:0;54747:19;:23;63944:61;63919:166;;;;-1:-1:-1;;;63919:166:0;;12434:2:1;63919:166:0;;;12416:21:1;12473:2;12453:18;;;12446:30;12512:34;12492:18;;;12485:62;12583:16;12563:18;;;12556:44;12617:19;;63919:166:0;12232:410:1;63919:166:0;-1:-1:-1;64106:5:0;;63493:808;-1:-1:-1;63493:808:0:o;63886:409::-;64150:12;;:22;;;;:12;;:22;64142:81;;;;-1:-1:-1;;;64142:81:0;;12434:2:1;64142:81:0;;;12416:21:1;12473:2;12453:18;;;12446:30;12512:34;12492:18;;;12485:62;12583:16;12563:18;;;12556:44;12617:19;;64142:81:0;12232:410:1;64142:81:0;-1:-1:-1;64237:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;63493:808:0:o;63886:409::-;63493:808;;;:::o;71611:142::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;12849:2:1;62896:69:0;;;12831:21:1;12888:2;12868:18;;;12861:30;12927:34;12907:18;;;12900:62;12998:13;12978:18;;;12971:41;13029:19;;62896:69:0;12647:407:1;62896:69:0;71699:16:::1;:14;:16::i;37137:126::-:0;37204:7;37230:26;:8;34725:4;37230:12;:26::i;:::-;37223:33;37137:126;-1:-1:-1;;37137:126:0:o;37387:305::-;37466:7;37447:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;37504:181:::1;37530:8;37556:35;37568:8;37578:12;37556:11;:35::i;:::-;37609:33;37621:8;37631:10;37609:11;:33::i;:::-;34781:12;37504:8;:181::i;:::-;37485:200;;35009:1;37387:305:::0;;;;:::o;40989:151::-;41065:6;41047:7;40069:37;34781:12;34774:20;-1:-1:-1;;40069:16:0;;;;:37::i;:::-;-1:-1:-1;41097:35:0::1;-1:-1:-1::0;;41097:17:0;::::1;39748:1;41130;41097:17;:35::i;41590:161::-:0;41671:6;41653:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41703:40:0::1;-1:-1:-1::0;;41703:17:0;::::1;39900:2;41741:1;41703:17;:40::i;23211:290::-:0;23267:14;23293:12;23308;23312:7;16142:3;16138:17;3426:26;16134:29;;15815:364;23308:12;23293:27;;;;23330:12;23345;23349:7;17248:2;17244:16;3426:26;17240:28;;17002:282;23345:12;23330:27;;23464:21;;;;23211:290;-1:-1:-1;;;23211:290:0:o;83310:182::-;83381:4;83404:36;;;;;:81;;-1:-1:-1;;81631:1:0;83444:41;;;83310:182::o;42028:174::-;42115:6;42097:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;42147:47:0::1;-1:-1:-1::0;;42147:17:0;::::1;40015:2;42192:1;42147:17;:47::i;37814:299::-:0;37891:7;37872:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;37929:177:::1;37955:8;37981:33;37993:8;38003:10;37981:11;:33::i;:::-;38032;38044:8;38054:10;38032:11;:33::i;:::-;34844:10;37504:8;:181::i;41817:147::-:0;41896:7;41878;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41922:35:0::1;-1:-1:-1::0;;41922:13:0;::::1;39953:2;41954;41922:13;:35::i;111010:643::-:0;111085:17;111187:41;;;111183:464;;-1:-1:-1;;111490:15:0;;;;;63493:808::o;111183:464::-;111625:10;111598:38;34011:127;41384:149;41459:6;41441:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41491:34:0::1;-1:-1:-1::0;;41491:17:0;::::1;39845:2;41523:1;41491:17;:34::i;41192:141::-:0;41268:7;41250;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41294:32:0::1;-1:-1:-1::0;;41294:13:0;::::1;39797:1;41323:2;41294:13;:32::i;38235:190::-:0;38312:7;38293:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;38338:80:::1;38347:8;38357:33;38369:8;38379:10;38357:11;:33::i;:::-;17248:2:::0;17244:16;;;3426:26;17240:28;34905:10:::1;37504:8;:181::i;29064:632::-:0;29119:16;29147:11;29168:12;29183;29187:7;17248:2;17244:16;3426:26;17240:28;;17002:282;29183:12;29168:27;;;;29305:4;29299:11;29292:18;;29360:3;29353:10;;29406:33;29419:7;29428:3;29434:4;29428:10;29406:12;:33::i;:::-;-1:-1:-1;29563:14:0;;;29579:4;29559:25;29553:4;29546:39;29626:17;;29064:632;;-1:-1:-1;29064:632:0:o;72505:179::-;72588:7;;;;72605:21;;;;;;;;;;;72641:36;;;72588:7;;;;13294:34:1;;;13359:2;13344:18;;13337:43;;;;72641:36:0;;13206:18:1;72641:36:0;;;;;;;72556:128;72505:179;:::o;82809:175::-;82940:24;;;;:17;;;;:24;;;;;:37;82809:175::o;69655:187::-;69747:6;;;;69763:17;;;;;;;;;;;69795:40;;69747:6;;;69763:17;69747:6;;69795:40;;69728:16;;69795:40;69718:124;69655:187;:::o;78985:474::-;79086:16;;79141:19;:12;79086:16;79141;:19::i;:::-;79133:27;-1:-1:-1;73658:2:0;3426:26;17248:2;17244:16;;;17240:28;74912:37;79170:52;;;;-1:-1:-1;;;79170:52:0;;13593:2:1;79170:52:0;;;13575:21:1;13632:2;13612:18;;;13605:30;13671:20;13651:18;;;13644:48;13709:18;;79170:52:0;13391:342:1;79170:52:0;79243:115;79275:23;-1:-1:-1;;79275:21:0;;;:23::i;:::-;79312:36;:28;-1:-1:-1;;79312:26:0;;;:28::i;:36::-;79243:18;:115::i;:::-;79232:126;-1:-1:-1;79376:47:0;79387:25;-1:-1:-1;;79387:23:0;;;:25::i;:::-;-1:-1:-1;110885:7:0;;;110873:19;;;110885:7;;110873:19;;110772:127;79376:47;79368:84;;;;-1:-1:-1;;;79368:84:0;;13940:2:1;79368:84:0;;;13922:21:1;13979:2;13959:18;;;13952:30;14018:26;13998:18;;;13991:54;14062:18;;79368:84:0;13738:348:1;79368:84:0;78985:474;;;:::o;75053:143::-;75118:6;75150:38;-1:-1:-1;;75150:15:0;;75118:6;75186:1;75150:15;:38::i;75310:136::-;75374:6;75406:32;-1:-1:-1;;75406:15:0;;73552:1;;75406:15;:32::i;75539:124::-;75602:7;75628:28;-1:-1:-1;;75628:11:0;;73599:1;75653:2;75628:11;:28::i;76007:172::-;76075:7;76101:71;73658:2;76131:37;73658:2;17248;17244:16;;;3426:26;17240:28;76131:37;:::i;:::-;-1:-1:-1;;76101:11:0;;;:71;76170:1;76101:11;:71::i;68133:95::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;12849:2:1;62896:69:0;;;12831:21:1;12888:2;12868:18;;;12861:30;12927:34;12907:18;;;12900:62;12998:13;12978:18;;;12971:41;13029:19;;62896:69:0;12647:407:1;62896:69:0;68195:26:::1;:24;:26::i;14411:359::-:0;14515:10;;14481:7;;14662:4;14653:14;;14737:26;;;;14653:14;14515:10;14737:5;:26::i;:::-;14730:33;14411:359;-1:-1:-1;;;;;14411:359:0:o;10829:578::-;10907:7;10931:26;10938:7;10947:9;10931:6;:26::i;:::-;10926:451;;10976:9;10989:35;11007:15;11014:7;15173:3;15169:17;;14962:268;11007:15;10999:24;;10989:9;:35::i;:::-;10973:51;;;11041:9;11054:29;11072:9;11064:18;;11054:9;:29::i;:::-;11141:186;;14588:31:1;11141:186:0;;;14576:44:1;14639:66;14743:3;14739:16;;;14735:25;;14721:12;;;14714:47;14791:15;14777:12;;;14770:37;14841:16;;;14837:25;14823:12;;;14816:47;11038:45:0;;-1:-1:-1;11097:17:0;;-1:-1:-1;14879:12:1;;11141:186:0;;;;;;;;;;;;11097:244;;11362:3;11355:11;;-1:-1:-1;;;11355:11:0;;;;;;;;:::i;10926:451::-;-1:-1:-1;11393:7:0;;10829:578;-1:-1:-1;10829:578:0:o;38947:164::-;39021:7;39047:57;35651:1;39074:5;39066:14;;;;;;;;:::i;:::-;:26;;;;:::i;:::-;-1:-1:-1;;39047:18:0;;;35651:1;39047:18;:57::i;38662:218::-;38803:7;38829:44;38844:5;38851:11;38844:5;38851:3;:11;:::i;:::-;-1:-1:-1;;38829:14:0;;;:44;38864:8;38829:14;:44::i;21877:221::-;21996:14;22074:11;22079:6;22074:2;:11;:::i;:::-;22073:17;;22089:1;22073:17;:::i;:::-;22029:62;;22037:30;22043:7;22052:6;22060;22037:5;:30::i;:::-;22029:62;;;21877:221;-1:-1:-1;;;;21877:221:0:o;20760:771::-;20875:14;20905:6;:11;;20915:1;20905:11;20901:59;;-1:-1:-1;20947:1:0;20932:17;;20901:59;20991:12;20995:7;17248:2;17244:16;3426:26;17240:28;;17002:282;20991:12;20973:30;;:15;;;;:6;:15;:::i;:::-;:30;20969:137;;;21026:68;21042:12;21046:7;16142:3;16138:17;3426:26;16134:29;;15815:364;21042:12;21026:68;;21056:12;21060:7;17248:2;17244:16;3426:26;17240:28;;17002:282;21056:12;21026:68;;21070:6;21086;21078:15;;21026;:68::i;:::-;21019:76;;-1:-1:-1;;;21019:76:0;;;;;;;;:::i;20969:137::-;21133:2;21123:6;:12;;;;21115:83;;;;-1:-1:-1;;;21115:83:0;;16004:2:1;21115:83:0;;;15986:21:1;16043:2;16023:18;;;16016:30;16082:34;16062:18;;;16055:62;16153:28;16133:18;;;16126:56;16199:19;;21115:83:0;15802:422:1;21115:83:0;21279:1;21270:10;;21209:15;21315:12;21319:7;16142:3;16138:17;3426:26;16134:29;;15815:364;21315:12;21300:27;;;-1:-1:-1;21337:13:0;8244:66;8214:12;;;8193:131;21489:17;;;;21483:24;21479:36;;;-1:-1:-1;;;;;20760:771:0:o;27792:902::-;27870:15;-1:-1:-1;;8728:15:0;;;;27897:69;;;;-1:-1:-1;;;27897:69:0;;16431:2:1;27897:69:0;;;16413:21:1;16470:2;16450:18;;;16443:30;16509:34;16489:18;;;16482:62;16580:10;16560:18;;;16553:38;16608:19;;27897:69:0;16229:404:1;27897:69:0;27984:16;27992:7;27984;:16::i;:::-;27976:72;;;;-1:-1:-1;;;27976:72:0;;16840:2:1;27976:72:0;;;16822:21:1;16879:2;16859:18;;;16852:30;16918:34;16898:18;;;16891:62;16989:13;16969:18;;;16962:41;17020:19;;27976:72:0;16638:407:1;27976:72:0;28058:12;28073;28077:7;17248:2;17244:16;3426:26;17240:28;;17002:282;28073:12;28058:27;;;;28095:15;28113:12;28117:7;16142:3;16138:17;3426:26;16134:29;;15815:364;28113:12;28095:30;;;;28136:11;28257:4;28251:11;28244:18;;28344:7;28339:3;28336:16;28333:94;;;28384:4;28378;28371:18;28333:94;28599:4;28590:7;28584:4;28575:7;28572:1;28565:5;28554:50;28550:55;28635:52;28656:15;28663:7;15173:3;15169:17;;14962:268;28656:15;12817:27;12821:2;12817:27;;;;12891:17;;12883:26;;12955:17;;12951:2;12947:26;;12567:446;28635:52;28625:62;27792:902;-1:-1:-1;;;;;;27792:902:0:o;75769:155::-;75832:7;75858:59;-1:-1:-1;;75858:11:0;;75832:7;73658:2;75832:7;75858:11;:59::i;76506:285::-;76616:14;;76663;-1:-1:-1;;76663:12:0;;;:14::i;:::-;76646:31;;76696:36;76725:6;52241:58;;18807:66:1;52241:58:0;;;18795:79:1;18890:12;;;18883:28;;;52111:7:0;;18927:12:1;;52241:58:0;;;;;;;;;;;;52231:69;;;;;;52224:76;;52042:265;;;;76696:36;76687:45;;76751:33;76765:6;76773:10;76751:13;:33::i;17885:399::-;18024:7;18043:12;18058;18062:7;16142:3;16138:17;3426:26;16134:29;;15815:364;18058:12;18043:27;;;;18154:12;18158:7;18154:3;:12::i;:::-;18147:4;18131:13;18138:6;18131:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;18127:77;;;-1:-1:-1;;18182:11:0;;;;;18127:77;18221:13;18228:6;18221:4;:13;:::i;:::-;18214:20;;18251:26;18257:7;18251:26;;18266:4;18272;18251:5;:26::i;68234:111::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;12849:2:1;62896:69:0;;;12831:21:1;12888:2;12868:18;;;12861:30;12927:34;12907:18;;;12900:62;12998:13;12978:18;;;12971:41;13029:19;;62896:69:0;12647:407:1;62896:69:0;68306:32:::1;67421:10:::0;68306:18:::1;:32::i;13552:462::-:0;13663:15;;13705:11;13712:4;13705;:11;:::i;:::-;13690:26;;13831:4;13825:11;13819:4;13816:21;13813:66;;;-1:-1:-1;13864:1:0;13813:66;13902:4;13910:1;13902:9;13898:51;;-1:-1:-1;;13927:11:0;;;;;13898:51;-1:-1:-1;;12821:2:0;12817:27;;;12891:17;;;;12883:26;;;12955:17;12951:2;12947:26;;13552:462::o;10399:132::-;10473:4;10515:9;10496:28;;:15;10503:7;15173:3;15169:17;;14962:268;10496:15;:28;;;;10399:132;-1:-1:-1;;;10399:132:0:o;5787:667::-;5841:13;;5897:2;5882:258;5905:2;5901:1;:6;;;5882:258;;;5925:11;5952:5;:1;5956;5952:5;:::i;:::-;5945:13;;:2;:13;;5925:34;;5982:14;5990:5;5982:7;:14::i;:::-;5973:23;;;;;;6014:1;:7;;6019:2;6014:7;6010:58;;6051:2;6041:12;;;;;6010:58;-1:-1:-1;6109:6:0;;5882:258;;;-1:-1:-1;6203:2:0;6188:260;6211:3;6207:1;:7;;;6188:260;;;6232:11;6259:5;:1;6263;6259:5;:::i;:::-;6252:13;;:2;:13;;6232:34;;6290:14;6298:5;6290:7;:14::i;:::-;6280:24;;;;;;6322:1;:6;;6327:1;6322:6;6318:58;;6359:2;6348:13;;;;;6318:58;-1:-1:-1;6417:6:0;;6188:260;;;;5787:667;;;:::o;19517:741::-;19663:17;19695:9;19708:15;19718:4;19708:9;:15::i;:::-;19692:31;;;19736:9;19749:15;19759:4;19749:9;:15::i;:::-;19733:31;;;19777:9;19790:17;19800:6;19790:9;:17::i;:::-;19774:33;;;19820:9;19833:17;19843:6;19833:9;:17::i;:::-;19817:33;;;20000:1;20062;20142;20204;19886:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19860:391;;19682:576;;;;19517:741;;;;;;:::o;9401:333::-;9458:8;9482:15;9489:7;15173:3;15169:17;;14962:268;9482:15;:31;;9501:12;9482:31;9478:74;;-1:-1:-1;9536:5:0;;9401:333;-1:-1:-1;9401:333:0:o;9478:74::-;9561:12;9576;9580:7;9576:3;:12::i;:::-;9711:4;9705:11;-1:-1:-1;9692:26:0;;9401:333;-1:-1:-1;;;9401:333:0:o;48338:227::-;48416:7;48436:17;48455:18;48477:27;48488:4;48494:9;48477:10;:27::i;:::-;48435:69;;;;48514:18;48526:5;48514:11;:18::i;17458:147::-;17511:7;17576:12;17580:7;17248:2;17244:16;3426:26;17240:28;;17002:282;17576:12;17561;17565:7;16142:3;16138:17;3426:26;16134:29;;15815:364;17561:12;:27;17554:34;;;;17458:147;;;:::o;5264:199::-;5314:14;5351:18;5367:1;5361:2;:7;;;;5351:9;:18::i;:::-;5340:29;;5393:13;;;;;;5405:1;5393:13;5427;5437:2;5427:9;:13::i;:::-;5416:24;;;;5264:199;-1:-1:-1;5264:199:0:o;46273:1279::-;46354:7;46363:12;46584:9;:16;46604:2;46584:22;46580:966;;46873:4;46858:20;;46852:27;46922:4;46907:20;;46901:27;46979:4;46964:20;;46958:27;46622:9;46950:36;47020:25;47031:4;46950:36;46852:27;46901;47020:10;:25::i;:::-;47013:32;;;;;;;;;46580:966;47066:9;:16;47086:2;47066:22;47062:484;;47335:4;47320:20;;47314:27;47385:4;47370:20;;47364:27;47425:23;47436:4;47314:27;47364;47425:10;:23::i;:::-;47418:30;;;;;;;;47062:484;-1:-1:-1;47495:1:0;;-1:-1:-1;47499:35:0;47062:484;46273:1279;;;;;:::o;44578:631::-;44655:20;44646:5;:29;;;;;;;;:::i;:::-;;44642:561;;44578:631;:::o;44642:561::-;44751:29;44742:5;:38;;;;;;;;:::i;:::-;;44738:465;;44796:34;;-1:-1:-1;;;44796:34:0;;19152:2:1;44796:34:0;;;19134:21:1;19191:2;19171:18;;;19164:30;19230:26;19210:18;;;19203:54;19274:18;;44796:34:0;18950:348:1;44738:465:0;44860:35;44851:5;:44;;;;;;;;:::i;:::-;;44847:356;;44911:41;;-1:-1:-1;;;44911:41:0;;19505:2:1;44911:41:0;;;19487:21:1;19544:2;19524:18;;;19517:30;19583:33;19563:18;;;19556:61;19634:18;;44911:41:0;19303:355:1;44847:356:0;44982:30;44973:5;:39;;;;;;;;:::i;:::-;;44969:234;;45028:44;;-1:-1:-1;;;45028:44:0;;19865:2:1;45028:44:0;;;19847:21:1;19904:2;19884:18;;;19877:30;19943:34;19923:18;;;19916:62;20014:4;19994:18;;;19987:32;20036:19;;45028:44:0;19663:398:1;44969:234:0;45102:30;45093:5;:39;;;;;;;;:::i;:::-;;45089:114;;45148:44;;-1:-1:-1;;;45148:44:0;;20268:2:1;45148:44:0;;;20250:21:1;20307:2;20287:18;;;20280:30;20346:34;20326:18;;;20319:62;20417:4;20397:18;;;20390:32;20439:19;;45148:44:0;20066:398:1;3699:1393:0;3751:10;3917:4;3912:9;;;;3963:15;;;;;3959:57;;-1:-1:-1;4001:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;3959:57::-;4034:7;:15;;4045:4;4034:15;4030:57;;-1:-1:-1;4072:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4030:57::-;4105:7;:15;;4116:4;4105:15;4101:57;;-1:-1:-1;4143:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4101:57::-;4176:7;:15;;4187:4;4176:15;4172:57;;-1:-1:-1;4214:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4172:57::-;4247:7;:15;;4258:4;4247:15;4243:57;;-1:-1:-1;4285:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4243:57::-;4318:7;:15;;4329:4;4318:15;4314:57;;-1:-1:-1;4356:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4314:57::-;4389:7;:15;;4400:4;4389:15;4385:57;;-1:-1:-1;4427:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4385:57::-;4460:7;:15;;4471:4;4460:15;4456:57;;-1:-1:-1;4498:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4456:57::-;4531:7;:15;;4542:4;4531:15;4527:57;;-1:-1:-1;4569:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4527:57::-;4602:7;:15;;4613:4;4602:15;4598:57;;-1:-1:-1;4640:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4598:57::-;4673:7;:15;;4684:4;4673:15;4669:57;;-1:-1:-1;4711:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4669:57::-;4744:7;:15;;4755:4;4744:15;4740:57;;-1:-1:-1;4782:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4740:57::-;4815:7;:15;;4826:4;4815:15;4811:57;;-1:-1:-1;4853:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4811:57::-;4886:7;:15;;4897:4;4886:15;4882:57;;-1:-1:-1;4924:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4882:57::-;4957:7;:15;;4968:4;4957:15;4953:57;;-1:-1:-1;4995:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4953:57::-;5028:7;:15;;5039:4;5028:15;5024:57;;-1:-1:-1;5066:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;49746:1603::-;49872:7;;50796:66;50783:79;;50779:161;;;-1:-1:-1;50894:1:0;;-1:-1:-1;50898:30:0;50878:51;;50779:161;50953:1;:7;;50958:2;50953:7;;:18;;;;;50964:1;:7;;50969:2;50964:7;;50953:18;50949:100;;;-1:-1:-1;51003:1:0;;-1:-1:-1;51007:30:0;50987:51;;50949:100;51160:24;;;51143:14;51160:24;;;;;;;;;20696:25:1;;;20769:4;20757:17;;20737:18;;;20730:45;;;;20791:18;;;20784:34;;;20834:18;;;20827:34;;;51160:24:0;;20668:19:1;;51160:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51160:24:0;;;;;;-1:-1:-1;;51198:20:0;;;51194:101;;51250:1;51254:29;51234:50;;;;;;;51194:101;51313:6;-1:-1:-1;51321:20:0;;-1:-1:-1;49746:1603:0;;;;;;;;:::o;48819:336::-;48929:7;;48987:66;48974:80;;48929:7;49080:25;49096:3;49081:18;;;49103:2;49080:25;:::i;:::-;49064:42;;49123:25;49134:4;49140:1;49143;49146;49123:10;:25::i;:::-;49116:32;;;;;;48819:336;;;;;;:::o;14:163:1:-;81:20;;141:10;130:22;;120:33;;110:61;;167:1;164;157:12;182:324;257:6;265;273;326:2;314:9;305:7;301:23;297:32;294:52;;;342:1;339;332:12;294:52;365:28;383:9;365:28;:::i;:::-;355:38;;412:37;445:2;434:9;430:18;412:37;:::i;:::-;402:47;;496:2;485:9;481:18;468:32;458:42;;182:324;;;;;:::o;703:184::-;755:77;752:1;745:88;852:4;849:1;842:15;876:4;873:1;866:15;892:777;934:5;987:3;980:4;972:6;968:17;964:27;954:55;;1005:1;1002;995:12;954:55;1041:6;1028:20;1067:18;1104:2;1100;1097:10;1094:36;;;1110:18;;:::i;:::-;1244:2;1238:9;1306:4;1298:13;;1149:66;1294:22;;;1318:2;1290:31;1286:40;1274:53;;;1342:18;;;1362:22;;;1339:46;1336:72;;;1388:18;;:::i;:::-;1428:10;1424:2;1417:22;1463:2;1455:6;1448:18;1509:3;1502:4;1497:2;1489:6;1485:15;1481:26;1478:35;1475:55;;;1526:1;1523;1516:12;1475:55;1590:2;1583:4;1575:6;1571:17;1564:4;1556:6;1552:17;1539:54;1637:1;1630:4;1625:2;1617:6;1613:15;1609:26;1602:37;1657:6;1648:15;;;;;;892:777;;;;:::o;1674:609::-;1794:6;1802;1810;1818;1871:4;1859:9;1850:7;1846:23;1842:34;1839:54;;;1889:1;1886;1879:12;1839:54;1912:28;1930:9;1912:28;:::i;:::-;1902:38;;1991:2;1980:9;1976:18;1963:32;2018:18;2010:6;2007:30;2004:50;;;2050:1;2047;2040:12;2004:50;2073:49;2114:7;2105:6;2094:9;2090:22;2073:49;:::i;:::-;2063:59;;;2156:4;2145:9;2141:20;2180:7;2176:2;2173:15;2170:35;;;2201:1;2198;2191:12;2170:35;1674:609;;;;-1:-1:-1;;;2239:2:1;2224:18;;;;;2261:16;;;1674:609::o;2288:252::-;2355:6;2363;2416:2;2404:9;2395:7;2391:23;2387:32;2384:52;;;2432:1;2429;2422:12;2384:52;2455:28;2473:9;2455:28;:::i;:::-;2445:38;2530:2;2515:18;;;;2502:32;;-1:-1:-1;;;2288:252:1:o;2909:154::-;2995:42;2988:5;2984:54;2977:5;2974:65;2964:93;;3053:1;3050;3043:12;3068:319;3135:6;3143;3196:2;3184:9;3175:7;3171:23;3167:32;3164:52;;;3212:1;3209;3202:12;3164:52;3235:28;3253:9;3235:28;:::i;:::-;3225:38;;3313:2;3302:9;3298:18;3285:32;3326:31;3351:5;3326:31;:::i;:::-;3376:5;3366:15;;;3068:319;;;;;:::o;3820:320::-;3888:6;3941:2;3929:9;3920:7;3916:23;3912:32;3909:52;;;3957:1;3954;3947:12;3909:52;3997:9;3984:23;4030:18;4022:6;4019:30;4016:50;;;4062:1;4059;4052:12;4016:50;4085:49;4126:7;4117:6;4106:9;4102:22;4085:49;:::i;4145:247::-;4204:6;4257:2;4245:9;4236:7;4232:23;4228:32;4225:52;;;4273:1;4270;4263:12;4225:52;4312:9;4299:23;4331:31;4356:5;4331:31;:::i;4397:320::-;4473:6;4481;4489;4542:2;4530:9;4521:7;4517:23;4513:32;4510:52;;;4558:1;4555;4548:12;4510:52;4581:28;4599:9;4581:28;:::i;:::-;4571:38;4656:2;4641:18;;4628:32;;-1:-1:-1;4707:2:1;4692:18;;;4679:32;;4397:320;-1:-1:-1;;;4397:320:1:o;4722:184::-;4780:6;4833:2;4821:9;4812:7;4808:23;4804:32;4801:52;;;4849:1;4846;4839:12;4801:52;4872:28;4890:9;4872:28;:::i;5629:184::-;5681:77;5678:1;5671:88;5778:4;5775:1;5768:15;5802:4;5799:1;5792:15;5818:128;5858:3;5889:1;5885:6;5882:1;5879:13;5876:39;;;5895:18;;:::i;:::-;-1:-1:-1;5931:9:1;;5818:128::o;5951:184::-;6003:77;6000:1;5993:88;6100:4;6097:1;6090:15;6124:4;6121:1;6114:15;9105:530;9146:3;9184:5;9178:12;9211:6;9206:3;9199:19;9236:1;9246:162;9260:6;9257:1;9254:13;9246:162;;;9322:4;9378:13;;;9374:22;;9368:29;9350:11;;;9346:20;;9339:59;9275:12;9246:162;;;9426:6;9423:1;9420:13;9417:87;;;9492:1;9485:4;9476:6;9471:3;9467:16;9463:27;9456:38;9417:87;-1:-1:-1;9549:2:1;9537:15;9554:66;9533:88;9524:98;;;;9624:4;9520:109;;9105:530;-1:-1:-1;;9105:530:1:o;9640:547::-;9858:4;9887:10;9936:2;9928:6;9924:15;9913:9;9906:34;9988:2;9980:6;9976:15;9971:2;9960:9;9956:18;9949:43;;10028:6;10023:2;10012:9;10008:18;10001:34;10071:6;10066:2;10055:9;10051:18;10044:34;10115:3;10109;10098:9;10094:19;10087:32;10136:45;10176:3;10165:9;10161:19;10153:6;10136:45;:::i;:::-;10128:53;9640:547;-1:-1:-1;;;;;;;9640:547:1:o;11569:217::-;11716:2;11705:9;11698:21;11679:4;11736:44;11776:2;11765:9;11761:18;11753:6;11736:44;:::i;11791:184::-;11843:77;11840:1;11833:88;11940:4;11937:1;11930:15;11964:4;11961:1;11954:15;14091:125;14131:4;14159:1;14156;14153:8;14150:34;;;14164:18;;:::i;:::-;-1:-1:-1;14201:9:1;;14091:125::o;15126:228::-;15166:7;15292:1;15224:66;15220:74;15217:1;15214:81;15209:1;15202:9;15195:17;15191:105;15188:131;;;15299:18;;:::i;:::-;-1:-1:-1;15339:9:1;;15126:228::o;15359:195::-;15397:4;15434;15431:1;15427:12;15466:4;15463:1;15459:12;15491:3;15486;15483:12;15480:38;;;15498:18;;:::i;:::-;15535:13;;;15359:195;-1:-1:-1;;;15359:195:1:o;15559:238::-;15597:7;15637:4;15634:1;15630:12;15669:4;15666:1;15662:12;15729:3;15723:4;15719:14;15714:3;15711:23;15704:3;15697:11;15690:19;15686:49;15683:75;;;15738:18;;:::i;:::-;15778:13;;15559:238;-1:-1:-1;;;15559:238:1:o;17169:1391::-;17891:34;17879:47;;17956:23;17951:2;17942:12;;17935:45;17999:66;18103:3;18099:16;;;18095:25;;18090:2;18081:12;;18074:47;18140:17;18182:2;18173:12;;18166:24;;;18224:16;;;18220:25;;18215:2;18206:12;;18199:47;18276:34;18271:2;18262:12;;18255:56;18342:3;18336;18327:13;;18320:26;18381:16;;;18377:25;;18371:3;18362:13;;18355:48;18428:3;18419:13;;18412:25;18472:16;;;18468:25;18462:3;18453:13;;18446:48;17127:3;18549;18540:13;;17115:16;-1:-1:-1;17147:11:1;;;18510:44;17050:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"Process","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"previousConfirmAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newConfirmAt","type":"uint256"}],"name":"SetConfirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"acceptableRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"activeReplicaConfirmedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_messageId","type":"bytes32"}],"name":"activeReplicaMessageStatus","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"}],"name":"activeReplicaNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"process","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"prove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"proveAndProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"uint256","name":"_confirmAt","type":"uint256"}],"name":"setConfirmation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"submitAttestation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"Process(uint32,bytes32)":{"notice":"Emitted when message is processed"},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"notice":"Emitted when a root's confirmation is modified by governance"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"}},"kind":"user","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"notice":"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed"},"initialize(uint32,address)":{"notice":"Initialize the replica"},"process(bytes)":{"notice":"Given formatted message, attempts to dispatch message payload to end recipient."},"prove(uint32,bytes,bytes32[32],uint256)":{"notice":"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf."},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"notice":"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message."},"setConfirmation(uint32,bytes32,uint256)":{"notice":"Set confirmAt for a given root"},"setUpdater(address)":{"notice":"Set Updater role"},"submitAttestation(bytes)":{"notice":"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event."}},"notice":"Track root updates on Home, prove and dispatch messages to end recipients.","version":1},"developerDoc":{"events":{"Process(uint32,bytes32)":{"params":{"messageHash":"The keccak256 hash of the message that was processed"}},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"params":{"newConfirmAt":"The new value of confirmAt","previousConfirmAt":"The previous value of confirmAt","root":"The root for which confirmAt has been set"}}},"kind":"dev","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"params":{"_root":"the Merkle root, submitted in an update, to check"},"returns":{"_0":"TRUE iff root has been submitted \u0026 timeout has expired"}},"initialize(uint32,address)":{"details":"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer","params":{"_remoteDomain":"The domain of the Home contract this follows","_updater":"The EVM id of the updater"}},"owner()":{"details":"Returns the address of the current owner."},"process(bytes)":{"details":"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.","params":{"_message":"Formatted message"}},"prove(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message","_proof":"Merkle proof of inclusion for leaf"},"returns":{"_0":"Returns true if proof was valid and `prove` call succeeded*"}},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if `prove` call returns false","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message (refer to UpdaterStorage.sol Message library)","_proof":"Merkle proof of inclusion for message's leaf"}},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setConfirmation(uint32,bytes32,uint256)":{"details":"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)","params":{"_confirmAt":"The new confirmation time. Set to 0 to \"delete\" a root.","_root":"The root for which to modify confirm time"}},"setUpdater(address)":{"details":"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)","params":{"_updater":"New Updater"}},"submitAttestation(bytes)":{"details":"Reverts if update doesn't build off latest committedRoot or if signature is invalid.","params":{"_attestation":"Attestation data and signature"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"title":"ReplicaManager","version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Process(uint32,bytes32)\":{\"params\":{\"messageHash\":\"The keccak256 hash of the message that was processed\"}},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"params\":{\"newConfirmAt\":\"The new value of confirmAt\",\"previousConfirmAt\":\"The previous value of confirmAt\",\"root\":\"The root for which confirmAt has been set\"}}},\"kind\":\"dev\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"params\":{\"_root\":\"the Merkle root, submitted in an update, to check\"},\"returns\":{\"_0\":\"TRUE iff root has been submitted \u0026 timeout has expired\"}},\"initialize(uint32,address)\":{\"details\":\"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer\",\"params\":{\"_remoteDomain\":\"The domain of the Home contract this follows\",\"_updater\":\"The EVM id of the updater\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"process(bytes)\":{\"details\":\"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.\",\"params\":{\"_message\":\"Formatted message\"}},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message\",\"_proof\":\"Merkle proof of inclusion for leaf\"},\"returns\":{\"_0\":\"Returns true if proof was valid and `prove` call succeeded*\"}},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if `prove` call returns false\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message (refer to UpdaterStorage.sol Message library)\",\"_proof\":\"Merkle proof of inclusion for message's leaf\"}},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"details\":\"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)\",\"params\":{\"_confirmAt\":\"The new confirmation time. Set to 0 to \\\"delete\\\" a root.\",\"_root\":\"The root for which to modify confirm time\"}},\"setUpdater(address)\":{\"details\":\"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)\",\"params\":{\"_updater\":\"New Updater\"}},\"submitAttestation(bytes)\":{\"details\":\"Reverts if update doesn't build off latest committedRoot or if signature is invalid.\",\"params\":{\"_attestation\":\"Attestation data and signature\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"ReplicaManager\",\"version\":1},\"userdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"Process(uint32,bytes32)\":{\"notice\":\"Emitted when message is processed\"},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"notice\":\"Emitted when a root's confirmation is modified by governance\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"}},\"kind\":\"user\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"notice\":\"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed\"},\"initialize(uint32,address)\":{\"notice\":\"Initialize the replica\"},\"process(bytes)\":{\"notice\":\"Given formatted message, attempts to dispatch message payload to end recipient.\"},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf.\"},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message.\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"notice\":\"Set confirmAt for a given root\"},\"setUpdater(address)\":{\"notice\":\"Set Updater role\"},\"submitAttestation(bytes)\":{\"notice\":\"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event.\"}},\"notice\":\"Track root updates on Home, prove and dispatch messages to end recipients.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ReplicaManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74","acceptableRoot(uint32,uint32,bytes32)":"15a046aa","activeReplicaConfirmedAt(uint32,bytes32)":"7dfdba28","activeReplicaMessageStatus(uint32,bytes32)":"63415514","activeReplicaNonce(uint32)":"b65672d3","initialize(uint32,address)":"8624c35c","localDomain()":"8d3638f4","owner()":"8da5cb5b","process(bytes)":"928bc4b2","prove(uint32,bytes,bytes32[32],uint256)":"4f63be3f","proveAndProcess(uint32,bytes,bytes32[32],uint256)":"68705275","renounceOwnership()":"715018a6","setConfirmation(uint32,bytes32,uint256)":"9df7d36d","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","submitAttestation(bytes)":"f646a512","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/ReplicaManager.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208f0d4c59e2f08b6ed876625d353416889edb4a17810e96f5bc4eb2b66d4c0dd064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208f0d4c59e2f08b6ed876625d353416889edb4a17810e96f5bc4eb2b66d4c0dd064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"42512:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;42512:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"42512:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d65f41e4095261b41dcfb6a6cca03835f684e04a6ec7338b26e37e77adab856f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d65f41e4095261b41dcfb6a6cca03835f684e04a6ec7338b26e37e77adab856f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"94517:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;94517:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"94517:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e521ec16ea37dcdd777eec2db88082e2defe600aded3178caa1893559bfc321064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e521ec16ea37dcdd777eec2db88082e2defe600aded3178caa1893559bfc321064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"91516:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;91516:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"91516:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220feb3f17f48b19f33ec25881e99153f6ffb9ec133b201153a7f75af53cf26a16d64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220feb3f17f48b19f33ec25881e99153f6ffb9ec133b201153a7f75af53cf26a16d64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33030:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33030:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33030:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220252889ea99f4d060b684d11be49367f79b773b69bf36d9b36c4b93ae54d5d79064736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220252889ea99f4d060b684d11be49367f79b773b69bf36d9b36c4b93ae54d5d79064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"782:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;782:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"782:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;3295:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;3295:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/ReplicaManager.sol:UpdaterStorage":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"}},"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"NewUpdater(address,address)":{"params":{"newUpdater":"The address of the new updater","oldUpdater":"The address of the old updater"}},"Update(uint32,uint32,bytes32,bytes)":{"params":{"homeDomain":"Domain of home contract","nonce":"Nonce of new merkle root","root":"New merkle root","signature":"Updater's signature on `homeDomain`, `nonce` and `root`"}}},"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"params\":{\"newUpdater\":\"The address of the new updater\",\"oldUpdater\":\"The address of the old updater\"}},\"Update(uint32,uint32,bytes32,bytes)\":{\"params\":{\"homeDomain\":\"Domain of home contract\",\"nonce\":\"Nonce of new merkle root\",\"root\":\"New merkle root\",\"signature\":\"Updater's signature on `homeDomain`, `nonce` and `root`\"}}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"UpdaterStorage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/ReplicaManager.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208c5fb2407775019b157ea125b93a1a55e918940081807b46322c7f52d22e14c264736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208c5fb2407775019b157ea125b93a1a55e918940081807b46322c7f52d22e14c264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80433:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"80433:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80457:33;;80489:1;80457:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;80457:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xf5e8ca349041b72711cf3659e9a89edc5a3f0188cb7b8285285c773e44217855\",\"urls\":[\"bzz-raw://698f93bc95671bcb2583e4096b1de70bcedf7b02053be58512c6c8fea47ad8d3\",\"dweb:/ipfs/QmcEUDMtGVpFM5ugf6Pb1mcLyigXK9ZZHQ2rD82QqSQKPT\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file +{"solidity/ReplicaManager.sol:AbstractGuardRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"AbstractGuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:AbstractNotaryRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"AbstractNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a0a83d0287d6b3bfd8e50d4364bff6024fca94f4f44158c6fff6d7bd0e52ba2664736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a0a83d0287d6b3bfd8e50d4364bff6024fca94f4f44158c6fff6d7bd0e52ba2664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"96689:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;96689:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"96689:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220791cba0f456ea113690031c6a55afc51fd8de048f41da85b89f956ddcb6fa60464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220791cba0f456ea113690031c6a55afc51fd8de048f41da85b89f956ddcb6fa60464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32270:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32270:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32270:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122092ab118aab8488d5aac04736bb7d595802a34a19f2c05876b46f3599af7f388964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122092ab118aab8488d5aac04736bb7d595802a34a19f2c05876b46f3599af7f388964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"46393:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;46393:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"46393:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220252f8e62e2ff652a2d9331a32227eef4613c8a897e3a7cfac4e0bc0711ae188764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220252f8e62e2ff652a2d9331a32227eef4613c8a897e3a7cfac4e0bc0711ae188764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"37467:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;37467:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"37467:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:EnumerableSet":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122055df74093a3725090dcf96105015e23e52964297e1a2529f3062573bee005b4f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122055df74093a3725090dcf96105015e23e52964297e1a2529f3062573bee005b4f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"52846:11368:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;52846:11368:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"52846:11368:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"EnumerableSet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:GlobalNotaryRegistry":{"code":"0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea264697066735822122059157c5b2485f571ff8758df23242344e47615d3b646f3fc4aad08515033245964736f6c634300080d0033","runtime-code":"0x6080604052600080fdfea264697066735822122059157c5b2485f571ff8758df23242344e47615d3b646f3fc4aad08515033245964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"48125:4371:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"48125:4371:0:-:0;;;;;","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"GlobalNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:GuardRegistry":{"code":"0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220d8653df998fdaf3f226e0096ef80a5bc1cc7a5b0a57e68e9796a04188e80442064736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220d8653df998fdaf3f226e0096ef80a5bc1cc7a5b0a57e68e9796a04188e80442064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"64216:3868:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"64216:3868:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66914:95;;;:::i;:::-;;;160:25:1;;;148:2;133:18;66914:95:0;;;;;;;;66801:107;;;;;;:::i;:::-;;:::i;:::-;;;557:42:1;545:55;;;527:74;;515:2;500:18;66801:107:0;381:226:1;66694:101:0;;;:::i;:::-;;;;;;;:::i;66914:95::-;66961:7;66987:15;:6;:13;:15::i;:::-;66980:22;;66914:95;:::o;66801:107::-;66858:7;66884:17;66858:7;66894:6;66884:9;:17::i;:::-;66877:24;66801:107;-1:-1:-1;;66801:107:0:o;66694:101::-;66738:16;66773:15;:6;:13;:15::i;60447:115::-;60510:7;60536:19;60544:3;56062:18;;55980:107;60904:156;60978:7;61028:22;61032:3;61044:5;61028:3;:22::i;:::-;61020:31;60904:156;-1:-1:-1;;;60904:156:0:o;61600:257::-;61663:16;61691:22;61716:19;61724:3;61716:7;:19::i;56429:118::-;56496:7;56522:3;:11;;56534:5;56522:18;;;;;;;;:::i;:::-;;;;;;;;;56515:25;;56429:118;;;;:::o;57087:109::-;57143:16;57178:3;:11;;57171:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57087:109;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;612:681::-;783:2;835:21;;;905:13;;808:18;;;927:22;;;754:4;;783:2;1006:15;;;;980:2;965:18;;;754:4;1049:218;1063:6;1060:1;1057:13;1049:218;;;1128:13;;1143:42;1124:62;1112:75;;1242:15;;;;1207:12;;;;1085:1;1078:9;1049:218;;;-1:-1:-1;1284:3:1;;612:681;-1:-1:-1;;;;;;612:681:1:o;1298:184::-;1350:77;1347:1;1340:88;1447:4;1444:1;1437:15;1471:4;1468:1;1461:15","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"GuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"allGuards()":"9fe03fa2","getGuard(uint256)":"629ddf69","guardsAmount()":"246c2449"}},"solidity/ReplicaManager.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220327149decfae2d41d1bee270f572b99fa3be2335f1e9b1f315fbefbaf83be43264736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220327149decfae2d41d1bee270f572b99fa3be2335f1e9b1f315fbefbaf83be43264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"85258:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;85258:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"85258:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:IMessageRecipient":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_origin","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint256","name":"_rootTimestamp","type":"uint256"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"handle","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_rootTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"handle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"IMessageRecipient\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"handle(uint32,uint32,bytes32,uint256,bytes)":"e4d16d62"}},"solidity/ReplicaManager.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/ReplicaManager.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"custom:oz-upgrades-unsafe-allow":"constructor constructor() { _disableInitializers(); } ``` ====","details":"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\"MyToken\", \"MTK\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\"MyToken\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```","events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor constructor() { _disableInitializers(); } ``` ====\",\"details\":\"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\\\"MyToken\\\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f9e4c7dc5d151b236f9264f903bb4cd1a70986338f4846708aa7937395914f8a64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f9e4c7dc5d151b236f9264f903bb4cd1a70986338f4846708aa7937395914f8a64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"71149:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;71149:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"71149:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122079c2aafd2e40ca3223c5407baca610ee6e69860782d73244303ca51c7c6debc164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122079c2aafd2e40ca3223c5407baca610ee6e69860782d73244303ca51c7c6debc164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80285:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;80285:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"80285:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManager.sol:ReplicaLib":{"code":"0x6098610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212201683c62ebbfa78a6c3d195b6a065da2517221675fde0dda5f19e2b8bce0a324564736f6c634300080d0033","runtime-code":"0x7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212201683c62ebbfa78a6c3d195b6a065da2517221675fde0dda5f19e2b8bce0a324564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"68148:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;68148:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"68148:2999:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69217:70;;69284:1;69217:70;;;;;168:25:1;;;156:2;141:18;69217:70:0;;;;;;;69155:56;;69209:1;69155:56;","abiDefinition":[{"inputs":[],"name":"MESSAGE_STATUS_NONE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_STATUS_PROCESSED","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"MESSAGE_STATUS_NONE":{"details":"Should not be possible to have 0x0 or 0x1 as valid Merkle root, so it's safe to use those values as NONE/PROCESSED"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"MESSAGE_STATUS_NONE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MESSAGE_STATUS_PROCESSED\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"MESSAGE_STATUS_NONE\":{\"details\":\"Should not be possible to have 0x0 or 0x1 as valid Merkle root, so it's safe to use those values as NONE/PROCESSED\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ReplicaLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"MESSAGE_STATUS_NONE()":"b0075818","MESSAGE_STATUS_PROCESSED()":"643d8086"}},"solidity/ReplicaManager.sol:ReplicaManager":{"code":"0x60a06040523480156200001157600080fd5b5060405162002f5238038062002f52833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612eb66200009c600039600081816102cf015281816109240152610f310152612eb66000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638d3638f4116100d8578063b65672d31161008c578063f2fde38b11610066578063f2fde38b146103c8578063f646a512146103db578063ffa1ad74146103ee57600080fd5b8063b65672d31461035f578063b7bc563e14610395578063ccbdf9c9146103a857600080fd5b8063928bc4b2116100bd578063928bc4b2146103245780639df7d36d146103375780639fe03fa21461034a57600080fd5b80638d3638f4146102ca5780638da5cb5b1461030657600080fd5b8063634155141161012f578063715018a611610114578063715018a61461026e5780637dfdba28146102765780638624c35c146102b757600080fd5b8063634155141461021a578063687052751461025b57600080fd5b80634f63be3f116101605780634f63be3f146101ba57806361bc3111146101cd578063629ddf69146101e257600080fd5b806315a046aa1461017c578063246c2449146101a4575b600080fd5b61018f61018a366004612824565b610408565b60405190151581526020015b60405180910390f35b6101ac610465565b60405190815260200161019b565b61018f6101c836600461293a565b610476565b6101e06101db3660046129cc565b6105f0565b005b6101f56101f0366004612a03565b610666565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101ac610228366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b6101e061026936600461293a565b610679565b6101e06106e0565b6101ac610284366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b6101e06102c53660046129cc565b610749565b6102f17f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019b565b60335473ffffffffffffffffffffffffffffffffffffffff166101f5565b6101e0610332366004612a46565b6108cb565b6101e0610345366004612a7b565b610c67565b610352610d5b565b60405161019b9190612aae565b6102f161036d366004612b08565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b6101e06103a3366004612b23565b610d67565b6065546101f59073ffffffffffffffffffffffffffffffffffffffff1681565b6101e06103d6366004612b23565b610e15565b6101e06103e9366004612a46565b610f0e565b6103f6600081565b60405160ff909116815260200161019b565b63ffffffff8316600090815260ce6020908152604080832054835260cd825280832084845260010190915281205480820361044757600091505061045e565b61045763ffffffff851682612b6f565b4210159150505b9392505050565b600061047160986110e9565b905090565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff1660028111156104c5576104c5612b87565b146105175760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105755760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e6500000000000000000000000000604482015260640161050e565b60006105ab8387602080602002604051908101604052809291908260208002808284376000920191909152508991506110f39050565b6000818152600184016020526040902054909150156105e05760009283526002919091016020526040909120555060016105e8565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106575760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b6106618282611199565b505050565b6000610673609883611296565b92915050565b61068584848484610476565b6106d15760405162461bcd60e51b815260206004820152600660248201527f2170726f76650000000000000000000000000000000000000000000000000000604482015260640161050e565b6106da836108cb565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b565b600061075560016112a2565b9050801561078a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6107926113f9565b61079c8383611199565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561084e8360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561066157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60006108d68261147e565b905060006108e962ffffff19831661148c565b905060006108fc62ffffff1983166114cc565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661095362ffffff1985166114f6565b63ffffffff16146109a65760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e0000000000000000000000000000000000000000604482015260640161050e565b60006109b762ffffff198616611517565b60008181526002840160205260409020549091506109d481611574565b610a205760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f636573736564000000000000000000000000604482015260640161050e565b610a3984610a3362ffffff198816611588565b83610408565b610a855760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e64730000000000000000000000000000604482015260640161050e565b60cb5460ff16600114610ada5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e7400000000000000000000000000000000000000000000604482015260640161050e565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b17610b1462ffffff1988166115a9565b50565b6000828152600284016020526040812060019055610b42610b3d62ffffff1988166115e0565b611601565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b7062ffffff198a16611643565b610b7f62ffffff198b16611664565b600087815260018a016020526040902054610bad610ba262ffffff198f16611685565b62ffffff19166116c4565b6040518663ffffffff1660e01b8152600401610bcd959493929190612c21565b600060405180830381600087803b158015610be757600080fd5b505af1158015610bfb573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610d119083908690869061171716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b6060610471609861172b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e7c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b73ffffffffffffffffffffffffffffffffffffffff8116610f055760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161050e565b610b1481611738565b6000610f19826117af565b9150506000610f2d8262ffffff19166118e9565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610faa5760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e00000000604482015260640161050e565b6000610fbb62ffffff1984166118fd565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116110365760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e7420737461746500604482015260640161050e565b600061104762ffffff198616611911565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6110cc610ba28a62ffffff1916611926565b6040516110d99190612c61565b60405180910390a4505050505050565b6000610673825490565b8260005b602081101561119157600183821c16600085836020811061111a5761111a612c74565b602002015190508160010361115a576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611187565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b50506001016110f7565b509392505050565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156111dd57506000610673565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b600061045e8383611959565b60008054610100900460ff161561133f578160ff1660011480156112c55750303b155b6113375760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b506000919050565b60005460ff8084169116106113bc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114765760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b610747611983565b600061067382610539611a09565b6000816114a162ffffff198216610539611a2d565b506114c3836114b1856001611b2e565b6114bc866002611b2e565b6001611b60565b91505b50919050565b6000816114e260015b62ffffff19831690611a2d565b506114c362ffffff19841660026004611b7f565b60008161150360016114d5565b506114c362ffffff198416602a6004611b7f565b6000806115328360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061155c8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906106735750506001141590565b60008161159560016114d5565b506114c362ffffff198416604e6004611b7f565b6000816115be62ffffff198216610539611a2d565b506114c3836115ce856002611b2e565b6115d9866003611b2e565b6002611b60565b6000816115ed60016114d5565b506114c362ffffff198416602e6020611baf565b600074010000000000000000000000000000000000000000820161163d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b81610673565b60008161165060016114d5565b506114c362ffffff19841660266004611b7f565b60008161167160016114d5565b506114c362ffffff19841660066020611baf565b60008161169a62ffffff198216610539611a2d565b506114c3836116aa856003611b2e565b601886901c6bffffffffffffffffffffffff166003611b60565b60606000806116e18460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117068483602001611d6d565b508181016020016040529052919050565b600091825260019092016020526040902055565b6060600061045e83611f12565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806117bc8382611a09565b905060286bffffffffffffffffffffffff601883901c16116118205760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161050e565b61184961183262ffffff198316611f6e565b611844610ba262ffffff198516611926565b611f83565b915061189861185d62ffffff1983166118e9565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6118e45760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161050e565b915091565b600061067362ffffff198316826004611b7f565b600061067362ffffff198316600480611b7f565b600061067362ffffff19831660086020611baf565b6000610673602861194981601886901c6bffffffffffffffffffffffff16612ca3565b62ffffff19851691906000611ffa565b600082600001828154811061197057611970612c74565b9060005260206000200154905092915050565b600054610100900460ff16611a005760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b61074733611738565b815160009060208401611a2464ffffffffff85168284612070565b95945050505050565b6000611a3983836120b7565b611b27576000611a58611a4c8560d81c90565b64ffffffffff166120da565b9150506000611a6d8464ffffffffff166120da565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161050e9190612c61565b5090919050565b600061045e6002836004811115611b4757611b47612b87565b611b519190612cba565b62ffffff198516906002611b7f565b6000611a2484611b708186612ca3565b62ffffff198816919085611ffa565b6000611b8c826020612cf7565b611b97906008612d1a565b60ff16611ba5858585611baf565b901c949350505050565b60008160ff16600003611bc45750600061045e565b611bdc8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611bf760ff841685612b6f565b1115611c6f57611c56611c188560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611c3e8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166121c4565b60405162461bcd60e51b815260040161050e9190612c61565b60208260ff161115611ce95760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161050e565b600882026000611d078660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611dea5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161050e565b611df383612232565b611e655760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161050e565b6000611e7f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611ea98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611ece5760206060fd5b8285848460045afa50611f08611ee48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611f6257602002820191906000526020600020905b815481526020019060010190808311611f4e575b50505050509050919050565b600061067362ffffff19831682602881611ffa565b600080611f9562ffffff198516611517565b9050611fee816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506105e8818461226f565b6000806120158660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061202e8661228b565b846120398784612b6f565b6120439190612b6f565b11156120565762ffffff199150506105e8565b6120608582612b6f565b9050611f088364ffffffffff1682865b60008061207d8385612b6f565b905060405181111561208d575060005b806000036120a25762ffffff1991505061045e565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166120cb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561214d5760006120f9826008612d1a565b60ff1685901c905061210a816122d3565b61ffff16841793508160ff1660101461212557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016120e0565b50600f5b60ff8160ff1610156121be57600061216a826008612d1a565b60ff1685901c905061217b816122d3565b61ffff16831792508160ff1660001461219657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612151565b50915091565b606060006121d1866120da565b91505060006121df866120da565b91505060006121ed866120da565b91505060006121fb866120da565b915050838383836040516020016122159493929190612d43565b604051602081830303815290604052945050505050949350505050565b600061223e8260d81c90565b64ffffffffff1664ffffffffff0361225857506000919050565b60006122638361228b565b60405110199392505050565b600080600061227e8585612305565b9150915061119181612373565b60006122a58260181c6bffffffffffffffffffffffff1690565b6122bd8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006122e560048360ff16901c61255f565b60ff1661ffff919091161760081b6122fc8261255f565b60ff1617919050565b600080825160410361233b5760208301516040840151606085015160001a61232f878285856126a6565b9450945050505061236c565b825160400361236457602083015160408401516123598683836127be565b93509350505061236c565b506000905060025b9250929050565b600081600481111561238757612387612b87565b0361238f5750565b60018160048111156123a3576123a3612b87565b036123f05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161050e565b600281600481111561240457612404612b87565b036124515760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161050e565b600381600481111561246557612465612b87565b036124d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b60048160048111156124ec576124ec612b87565b03610b145760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b600060f08083179060ff8216900361257a5750603092915050565b8060ff1660f10361258e5750603192915050565b8060ff1660f2036125a25750603292915050565b8060ff1660f3036125b65750603392915050565b8060ff1660f4036125ca5750603492915050565b8060ff1660f5036125de5750603592915050565b8060ff1660f6036125f25750603692915050565b8060ff1660f7036126065750603792915050565b8060ff1660f80361261a5750603892915050565b8060ff1660f90361262e5750603992915050565b8060ff1660fa036126425750606192915050565b8060ff1660fb036126565750606292915050565b8060ff1660fc0361266a5750606392915050565b8060ff1660fd0361267e5750606492915050565b8060ff1660fe036126925750606592915050565b8060ff1660ff036114c65750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126dd57506000905060036127b5565b8460ff16601b141580156126f557508460ff16601c14155b1561270657506000905060046127b5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561275a573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166127ae576000600192509250506127b5565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816127f460ff86901c601b612b6f565b9050612802878288856126a6565b935093505050935093915050565b803563ffffffff811681146113f457600080fd5b60008060006060848603121561283957600080fd5b61284284612810565b925061285060208501612810565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126128a057600080fd5b813567ffffffffffffffff808211156128bb576128bb612860565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561290157612901612860565b8160405283815286602085880101111561291a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561295157600080fd5b61295a85612810565b9350602085013567ffffffffffffffff81111561297657600080fd5b6129828782880161288f565b93505061044085018681111561299757600080fd5b9396929550505060409290920191903590565b73ffffffffffffffffffffffffffffffffffffffff81168114610b1457600080fd5b600080604083850312156129df57600080fd5b6129e883612810565b915060208301356129f8816129aa565b809150509250929050565b600060208284031215612a1557600080fd5b5035919050565b60008060408385031215612a2f57600080fd5b612a3883612810565b946020939093013593505050565b600060208284031215612a5857600080fd5b813567ffffffffffffffff811115612a6f57600080fd5b6105e88482850161288f565b600080600060608486031215612a9057600080fd5b612a9984612810565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612afc57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612aca565b50909695505050505050565b600060208284031215612b1a57600080fd5b61045e82612810565b600060208284031215612b3557600080fd5b813561045e816129aa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612b8257612b82612b40565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612bdc57602081850181015186830182015201612bc0565b81811115612bee576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612c5660a0830184612bb6565b979650505050505050565b60208152600061045e6020830184612bb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612cb557612cb5612b40565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612cf257612cf2612b40565b500290565b600060ff821660ff841680821015612d1157612d11612b40565b90039392505050565b600060ff821660ff84168160ff0481118215151615612d3b57612d3b612b40565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611f0856fea2646970667358221220fce2fcfae6e4784100dcfa09c5fc7f416a04dc2f803ffcb15a7730e07d8204ec64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106101775760003560e01c80638d3638f4116100d8578063b65672d31161008c578063f2fde38b11610066578063f2fde38b146103c8578063f646a512146103db578063ffa1ad74146103ee57600080fd5b8063b65672d31461035f578063b7bc563e14610395578063ccbdf9c9146103a857600080fd5b8063928bc4b2116100bd578063928bc4b2146103245780639df7d36d146103375780639fe03fa21461034a57600080fd5b80638d3638f4146102ca5780638da5cb5b1461030657600080fd5b8063634155141161012f578063715018a611610114578063715018a61461026e5780637dfdba28146102765780638624c35c146102b757600080fd5b8063634155141461021a578063687052751461025b57600080fd5b80634f63be3f116101605780634f63be3f146101ba57806361bc3111146101cd578063629ddf69146101e257600080fd5b806315a046aa1461017c578063246c2449146101a4575b600080fd5b61018f61018a366004612824565b610408565b60405190151581526020015b60405180910390f35b6101ac610465565b60405190815260200161019b565b61018f6101c836600461293a565b610476565b6101e06101db3660046129cc565b6105f0565b005b6101f56101f0366004612a03565b610666565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101ac610228366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b6101e061026936600461293a565b610679565b6101e06106e0565b6101ac610284366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b6101e06102c53660046129cc565b610749565b6102f17f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019b565b60335473ffffffffffffffffffffffffffffffffffffffff166101f5565b6101e0610332366004612a46565b6108cb565b6101e0610345366004612a7b565b610c67565b610352610d5b565b60405161019b9190612aae565b6102f161036d366004612b08565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b6101e06103a3366004612b23565b610d67565b6065546101f59073ffffffffffffffffffffffffffffffffffffffff1681565b6101e06103d6366004612b23565b610e15565b6101e06103e9366004612a46565b610f0e565b6103f6600081565b60405160ff909116815260200161019b565b63ffffffff8316600090815260ce6020908152604080832054835260cd825280832084845260010190915281205480820361044757600091505061045e565b61045763ffffffff851682612b6f565b4210159150505b9392505050565b600061047160986110e9565b905090565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff1660028111156104c5576104c5612b87565b146105175760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105755760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e6500000000000000000000000000604482015260640161050e565b60006105ab8387602080602002604051908101604052809291908260208002808284376000920191909152508991506110f39050565b6000818152600184016020526040902054909150156105e05760009283526002919091016020526040909120555060016105e8565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106575760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b6106618282611199565b505050565b6000610673609883611296565b92915050565b61068584848484610476565b6106d15760405162461bcd60e51b815260206004820152600660248201527f2170726f76650000000000000000000000000000000000000000000000000000604482015260640161050e565b6106da836108cb565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b565b600061075560016112a2565b9050801561078a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6107926113f9565b61079c8383611199565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561084e8360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561066157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60006108d68261147e565b905060006108e962ffffff19831661148c565b905060006108fc62ffffff1983166114cc565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661095362ffffff1985166114f6565b63ffffffff16146109a65760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e0000000000000000000000000000000000000000604482015260640161050e565b60006109b762ffffff198616611517565b60008181526002840160205260409020549091506109d481611574565b610a205760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f636573736564000000000000000000000000604482015260640161050e565b610a3984610a3362ffffff198816611588565b83610408565b610a855760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e64730000000000000000000000000000604482015260640161050e565b60cb5460ff16600114610ada5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e7400000000000000000000000000000000000000000000604482015260640161050e565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b17610b1462ffffff1988166115a9565b50565b6000828152600284016020526040812060019055610b42610b3d62ffffff1988166115e0565b611601565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b7062ffffff198a16611643565b610b7f62ffffff198b16611664565b600087815260018a016020526040902054610bad610ba262ffffff198f16611685565b62ffffff19166116c4565b6040518663ffffffff1660e01b8152600401610bcd959493929190612c21565b600060405180830381600087803b158015610be757600080fd5b505af1158015610bfb573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610d119083908690869061171716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b6060610471609861172b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e7c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b73ffffffffffffffffffffffffffffffffffffffff8116610f055760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161050e565b610b1481611738565b6000610f19826117af565b9150506000610f2d8262ffffff19166118e9565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610faa5760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e00000000604482015260640161050e565b6000610fbb62ffffff1984166118fd565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116110365760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e7420737461746500604482015260640161050e565b600061104762ffffff198616611911565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6110cc610ba28a62ffffff1916611926565b6040516110d99190612c61565b60405180910390a4505050505050565b6000610673825490565b8260005b602081101561119157600183821c16600085836020811061111a5761111a612c74565b602002015190508160010361115a576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611187565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b50506001016110f7565b509392505050565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156111dd57506000610673565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b600061045e8383611959565b60008054610100900460ff161561133f578160ff1660011480156112c55750303b155b6113375760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b506000919050565b60005460ff8084169116106113bc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114765760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b610747611983565b600061067382610539611a09565b6000816114a162ffffff198216610539611a2d565b506114c3836114b1856001611b2e565b6114bc866002611b2e565b6001611b60565b91505b50919050565b6000816114e260015b62ffffff19831690611a2d565b506114c362ffffff19841660026004611b7f565b60008161150360016114d5565b506114c362ffffff198416602a6004611b7f565b6000806115328360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061155c8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906106735750506001141590565b60008161159560016114d5565b506114c362ffffff198416604e6004611b7f565b6000816115be62ffffff198216610539611a2d565b506114c3836115ce856002611b2e565b6115d9866003611b2e565b6002611b60565b6000816115ed60016114d5565b506114c362ffffff198416602e6020611baf565b600074010000000000000000000000000000000000000000820161163d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b81610673565b60008161165060016114d5565b506114c362ffffff19841660266004611b7f565b60008161167160016114d5565b506114c362ffffff19841660066020611baf565b60008161169a62ffffff198216610539611a2d565b506114c3836116aa856003611b2e565b601886901c6bffffffffffffffffffffffff166003611b60565b60606000806116e18460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117068483602001611d6d565b508181016020016040529052919050565b600091825260019092016020526040902055565b6060600061045e83611f12565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806117bc8382611a09565b905060286bffffffffffffffffffffffff601883901c16116118205760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161050e565b61184961183262ffffff198316611f6e565b611844610ba262ffffff198516611926565b611f83565b915061189861185d62ffffff1983166118e9565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6118e45760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161050e565b915091565b600061067362ffffff198316826004611b7f565b600061067362ffffff198316600480611b7f565b600061067362ffffff19831660086020611baf565b6000610673602861194981601886901c6bffffffffffffffffffffffff16612ca3565b62ffffff19851691906000611ffa565b600082600001828154811061197057611970612c74565b9060005260206000200154905092915050565b600054610100900460ff16611a005760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b61074733611738565b815160009060208401611a2464ffffffffff85168284612070565b95945050505050565b6000611a3983836120b7565b611b27576000611a58611a4c8560d81c90565b64ffffffffff166120da565b9150506000611a6d8464ffffffffff166120da565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161050e9190612c61565b5090919050565b600061045e6002836004811115611b4757611b47612b87565b611b519190612cba565b62ffffff198516906002611b7f565b6000611a2484611b708186612ca3565b62ffffff198816919085611ffa565b6000611b8c826020612cf7565b611b97906008612d1a565b60ff16611ba5858585611baf565b901c949350505050565b60008160ff16600003611bc45750600061045e565b611bdc8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611bf760ff841685612b6f565b1115611c6f57611c56611c188560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611c3e8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166121c4565b60405162461bcd60e51b815260040161050e9190612c61565b60208260ff161115611ce95760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161050e565b600882026000611d078660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611dea5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161050e565b611df383612232565b611e655760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161050e565b6000611e7f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611ea98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611ece5760206060fd5b8285848460045afa50611f08611ee48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611f6257602002820191906000526020600020905b815481526020019060010190808311611f4e575b50505050509050919050565b600061067362ffffff19831682602881611ffa565b600080611f9562ffffff198516611517565b9050611fee816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506105e8818461226f565b6000806120158660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061202e8661228b565b846120398784612b6f565b6120439190612b6f565b11156120565762ffffff199150506105e8565b6120608582612b6f565b9050611f088364ffffffffff1682865b60008061207d8385612b6f565b905060405181111561208d575060005b806000036120a25762ffffff1991505061045e565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166120cb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561214d5760006120f9826008612d1a565b60ff1685901c905061210a816122d3565b61ffff16841793508160ff1660101461212557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016120e0565b50600f5b60ff8160ff1610156121be57600061216a826008612d1a565b60ff1685901c905061217b816122d3565b61ffff16831792508160ff1660001461219657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612151565b50915091565b606060006121d1866120da565b91505060006121df866120da565b91505060006121ed866120da565b91505060006121fb866120da565b915050838383836040516020016122159493929190612d43565b604051602081830303815290604052945050505050949350505050565b600061223e8260d81c90565b64ffffffffff1664ffffffffff0361225857506000919050565b60006122638361228b565b60405110199392505050565b600080600061227e8585612305565b9150915061119181612373565b60006122a58260181c6bffffffffffffffffffffffff1690565b6122bd8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006122e560048360ff16901c61255f565b60ff1661ffff919091161760081b6122fc8261255f565b60ff1617919050565b600080825160410361233b5760208301516040840151606085015160001a61232f878285856126a6565b9450945050505061236c565b825160400361236457602083015160408401516123598683836127be565b93509350505061236c565b506000905060025b9250929050565b600081600481111561238757612387612b87565b0361238f5750565b60018160048111156123a3576123a3612b87565b036123f05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161050e565b600281600481111561240457612404612b87565b036124515760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161050e565b600381600481111561246557612465612b87565b036124d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b60048160048111156124ec576124ec612b87565b03610b145760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b600060f08083179060ff8216900361257a5750603092915050565b8060ff1660f10361258e5750603192915050565b8060ff1660f2036125a25750603292915050565b8060ff1660f3036125b65750603392915050565b8060ff1660f4036125ca5750603492915050565b8060ff1660f5036125de5750603592915050565b8060ff1660f6036125f25750603692915050565b8060ff1660f7036126065750603792915050565b8060ff1660f80361261a5750603892915050565b8060ff1660f90361262e5750603992915050565b8060ff1660fa036126425750606192915050565b8060ff1660fb036126565750606292915050565b8060ff1660fc0361266a5750606392915050565b8060ff1660fd0361267e5750606492915050565b8060ff1660fe036126925750606592915050565b8060ff1660ff036114c65750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126dd57506000905060036127b5565b8460ff16601b141580156126f557508460ff16601c14155b1561270657506000905060046127b5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561275a573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166127ae576000600192509250506127b5565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816127f460ff86901c601b612b6f565b9050612802878288856126a6565b935093505050935093915050565b803563ffffffff811681146113f457600080fd5b60008060006060848603121561283957600080fd5b61284284612810565b925061285060208501612810565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126128a057600080fd5b813567ffffffffffffffff808211156128bb576128bb612860565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561290157612901612860565b8160405283815286602085880101111561291a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561295157600080fd5b61295a85612810565b9350602085013567ffffffffffffffff81111561297657600080fd5b6129828782880161288f565b93505061044085018681111561299757600080fd5b9396929550505060409290920191903590565b73ffffffffffffffffffffffffffffffffffffffff81168114610b1457600080fd5b600080604083850312156129df57600080fd5b6129e883612810565b915060208301356129f8816129aa565b809150509250929050565b600060208284031215612a1557600080fd5b5035919050565b60008060408385031215612a2f57600080fd5b612a3883612810565b946020939093013593505050565b600060208284031215612a5857600080fd5b813567ffffffffffffffff811115612a6f57600080fd5b6105e88482850161288f565b600080600060608486031215612a9057600080fd5b612a9984612810565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612afc57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612aca565b50909695505050505050565b600060208284031215612b1a57600080fd5b61045e82612810565b600060208284031215612b3557600080fd5b813561045e816129aa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612b8257612b82612b40565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612bdc57602081850181015186830182015201612bc0565b81811115612bee576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612c5660a0830184612bb6565b979650505050505050565b60208152600061045e6020830184612bb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612cb557612cb5612b40565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612cf257612cf2612b40565b500290565b600060ff821660ff841680821015612d1157612d11612b40565b90039392505050565b600060ff821660ff84168160ff0481118215151615612d3b57612d3b612b40565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611f0856fea2646970667358221220fce2fcfae6e4784100dcfa09c5fc7f416a04dc2f803ffcb15a7730e07d8204ec64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"118688:12750:0:-:0;;;120734:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115172:26;;;;118688:12750;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;118688:12750:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"118688:12750:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;127704:361;;;;;;:::i;:::-;;:::i;:::-;;;676:14:1;;669:22;651:41;;639:2;624:18;127704:361:0;;;;;;;;66914:95;;;:::i;:::-;;;849:25:1;;;837:2;822:18;66914:95:0;703:177:1;128727:1028:0;;;;;;:::i;:::-;;:::i;126405:158::-;;;;;;:::i;:::-;;:::i;:::-;;66801:107;;;;;;:::i;:::-;;:::i;:::-;;;3314:42:1;3302:55;;;3284:74;;3272:2;3257:18;66801:107:0;3138:226:1;122037:230:0;;;;;;:::i;:::-;122204:29;;;;;122162:7;122204:29;;;:14;:29;;;;;;;;;122192:42;;:11;:42;;;;;:68;;;:56;;;;:68;;;;;122037:230;123990:271;;;;;;:::i;:::-;;:::i;117488:57::-;;;:::i;121817:214::-;;;;;;:::i;:::-;121977:29;;;;;121935:7;121977:29;;;:14;:29;;;;;;;;;121965:42;;:11;:42;;;;;:59;;;:52;;;;:59;;;;;121817:214;121302:295;;;;;;:::i;:::-;;:::i;113961:35::-;;;;;;;;3982:10:1;3970:23;;;3952:42;;3940:2;3925:18;113961:35:0;3808:192:1;111644:85:0;111716:6;;;;111644:85;;124699:1415;;;;;;:::i;:::-;;:::i;126914:423::-;;;;;;:::i;:::-;;:::i;66694:101::-;;;:::i;:::-;;;;;;;:::i;121658:153::-;;;;;;:::i;:::-;121768:29;;;;121731:6;121768:29;;;:14;:29;;;;;;;;;121756:42;;:11;:42;;;;;:48;;;121658:153;117162:133;;;;;;:::i;:::-;;:::i;114543:39::-;;;;;;;;;112526:198;;;;;;:::i;:::-;;:::i;122757:801::-;;;;;;:::i;:::-;;:::i;68110:33::-;;68142:1;68110:33;;;;;6487:4:1;6475:17;;;6457:36;;6445:2;6430:18;68110:33:0;6315:184:1;127704:361:0;127887:29;;;127843:4;127887:29;;;:14;:29;;;;;;;;;127875:42;;:11;:42;;;;;:59;;;:52;;:59;;;;;;127948:10;;;127944:53;;127981:5;127974:12;;;;;127944:53;128032:26;;;;:5;:26;:::i;:::-;128013:15;:45;;128006:52;;;127704:361;;;;;;:::o;66914:95::-;66961:7;66987:15;:6;:13;:15::i;:::-;66980:22;;66914:95;:::o;128727:1028::-;128918:19;;;;;;;;;;128996:29;;;128886:4;128996:29;;;:14;:29;;;;;;;128984:42;;:11;:42;;;;;;129103:31;129085:14;;;;;;;:49;;;;;;;;:::i;:::-;;129077:80;;;;-1:-1:-1;;;129077:80:0;;7217:2:1;129077:80:0;;;7199:21:1;7256:2;7236:18;;;7229:30;7295:20;7275:18;;;7268:48;7333:18;;129077:80:0;;;;;;;;;69209:1;129252:28;;;:21;;;:28;;;;;;:62;129231:128;;;;-1:-1:-1;;;129231:128:0;;7564:2:1;129231:128:0;;;7546:21:1;7603:2;7583:18;;;7576:30;7642:21;7622:18;;;7615:49;7681:18;;129231:128:0;7362:343:1;129231:128:0;129427:23;129453:43;129474:5;129481:6;129453:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;129489:6:0;;-1:-1:-1;129453:20:0;;-1:-1:-1;129453:43:0:i;:::-;129588:34;;;;:17;;;:34;;;;;;129427:69;;-1:-1:-1;129588:39:0;129584:143;;70782:35;;;;:21;;;;;:35;;;;;;:45;-1:-1:-1;129712:4:0;129705:11;;129584:143;129743:5;129736:12;;;;;128727:1028;;;;;;;:::o;126405:158::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;126527:29:::1;126538:7;126547:8;126527:10;:29::i;:::-;;126405:158:::0;;:::o;66801:107::-;66858:7;66884:17;:6;66894;66884:9;:17::i;:::-;66877:24;66801:107;-1:-1:-1;;66801:107:0:o;123990:271::-;124170:46;124176:13;124191:8;124201:6;124209;124170:5;:46::i;:::-;124162:65;;;;-1:-1:-1;;;124162:65:0;;8273:2:1;124162:65:0;;;8255:21:1;8312:1;8292:18;;;8285:29;8350:8;8330:18;;;8323:36;8376:18;;124162:65:0;8071:329:1;124162:65:0;124237:17;124245:8;124237:7;:17::i;:::-;123990:271;;;;:::o;117488:57::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;117488:57::o;121302:295::-;106824:19;106846:25;106869:1;106846:22;:25::i;:::-;106824:47;;106885:14;106881:65;;;106915:13;:20;;;;;;;;106881:65;121391:29:::1;:27;:29::i;:::-;121430:35;121441:13;121456:8;121430:10;:35::i;:::-;-1:-1:-1::0;121508:7:0::1;:11:::0;;;::::1;121518:1;121508:11;::::0;;121561:29:::1;121576:13:::0;130044:12;;130059:1;130044:16;129878:20;130080:25;;;:11;:25;;;;;70254:36;;;;;;;70300:37;;;;;;;;;;;130143:12;:27;;;130158:12;129814:363;-1:-1:-1;129814:363:0;121561:29:::1;121529;::::0;::::1;;::::0;;;:14:::1;:29;::::0;;;;:61;106966:99;;;;107016:5;107000:21;;;;;;107040:14;;-1:-1:-1;6457:36:1;;107040:14:0;;6445:2:1;6430:18;107040:14:0;;;;;;;106814:257;121302:295;;:::o;124699:1415::-;124756:10;124769:22;:8;:20;:22::i;:::-;124756:35;-1:-1:-1;124801:15:0;124819:11;-1:-1:-1;;124819:9:0;;;:11::i;:::-;124801:29;-1:-1:-1;124840:20:0;124863:16;-1:-1:-1;;124863:14:0;;;:16::i;:::-;124938:29;;;;124889:34;124938:29;;;:14;:29;;;;;;;;;124926:42;;:11;:42;;;;;124840:39;;-1:-1:-1;125063:11:0;125038:36;:21;-1:-1:-1;;125038:19:0;;;:21::i;:::-;:36;;;125030:61;;;;-1:-1:-1;;;125030:61:0;;8806:2:1;125030:61:0;;;8788:21:1;8845:2;8825:18;;;8818:30;8884:14;8864:18;;;8857:42;8916:18;;125030:61:0;8604:336:1;125030:61:0;125143:20;125166:11;-1:-1:-1;;125166:9:0;;;:11::i;:::-;125187:13;125203:35;;;:21;;;:35;;;;;;125143:34;;-1:-1:-1;125256:33:0;125203:35;125256:26;:33::i;:::-;125248:66;;;;-1:-1:-1;;;125248:66:0;;9147:2:1;125248:66:0;;;9129:21:1;9186:2;9166:18;;;9159:30;9225:22;9205:18;;;9198:50;9265:18;;125248:66:0;8945:344:1;125248:66:0;125345:65;125360:13;125375:27;-1:-1:-1;;125375:25:0;;;:27::i;:::-;125404:5;125345:14;:65::i;:::-;125324:130;;;;-1:-1:-1;;;125324:130:0;;9496:2:1;125324:130:0;;;9478:21:1;9535:2;9515:18;;;9508:30;9574:20;9554:18;;;9547:48;9612:18;;125324:130:0;9294:342:1;125324:130:0;125507:7;;;;;:12;125499:35;;;;-1:-1:-1;;;125499:35:0;;9843:2:1;125499:35:0;;;9825:21:1;9882:2;9862:18;;;9855:30;9921:12;9901:18;;;9894:40;9951:18;;125499:35:0;9641:334:1;125499:35:0;125544:7;:11;;;;;;125565:21;125576:9;-1:-1:-1;;125576:7:0;;;:9::i;:::-;112526:198;;125565:21;70782:35;;;;:21;;;:35;;;;;69284:1;70782:45;;125747:43;125770:19;-1:-1:-1;;125770:17:0;;;:19::i;:::-;125747:22;:43::i;:::-;125727:63;-1:-1:-1;125800:35:0;;;;125849:13;125876:15;-1:-1:-1;;125876:13:0;;;:15::i;:::-;125905:16;-1:-1:-1;;125905:14:0;;;:16::i;:::-;125935:24;;;;:17;;;:24;;;;;;125973:17;:9;-1:-1:-1;;125973:7:0;;;:9::i;:::-;-1:-1:-1;;125973:15:0;;:17::i;:::-;125800:200;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;126015:36:0;;126038:12;;-1:-1:-1;126015:36:0;;;;-1:-1:-1;126015:36:0;;;;;-1:-1:-1;;126096:7:0;:11;;;;126106:1;126096:11;;;-1:-1:-1;;;;;;124699:1415:0:o;126914:423::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;127104:29:::1;::::0;;::::1;127055:34;127104:29:::0;;;:14:::1;:29;::::0;;;;;;;;127092:42;;:11:::1;:42:::0;;;;;127173:24;;;:17:::1;::::0;::::1;:24:::0;;;;;;;127092:42;;127207:39:::1;::::0;127092:42;;127191:5;;127235:10;;127207:20:::1;:39;:::i;:::-;127261:69;::::0;;11241:25:1;;;11297:2;11282:18;;11275:34;;;127292:5:0;;127261:69:::1;::::0;::::1;::::0;::::1;::::0;11214:18:1;127261:69:0::1;;;;;;;127045:292;;126914:423:::0;;;:::o;66694:101::-;66738:16;66773:15;:6;:13;:15::i;117162:133::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;117254:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;117162:133::o;112526:198::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;112614:22:::1;::::0;::::1;112606:73;;;::::0;-1:-1:-1;;;112606:73:0;;11522:2:1;112606:73:0::1;::::0;::::1;11504:21:1::0;11561:2;11541:18;;;11534:30;11600:34;11580:18;;;11573:62;11671:8;11651:18;;;11644:36;11697:19;;112606:73:0::1;11320:402:1::0;112606:73:0::1;112689:28;112708:8;112689:18;:28::i;122757:801::-:0;122833:13;122850:30;122867:12;122850:16;:30::i;:::-;122830:50;;;122890:19;122912:25;:5;:23;;;;:25::i;:::-;122890:47;;122971:11;122955:27;;:12;:27;;;122947:68;;;;-1:-1:-1;;;122947:68:0;;11929:2:1;122947:68:0;;;11911:21:1;11968:2;11948:18;;;11941:30;12007;11987:18;;;11980:58;12055:18;;122947:68:0;11727:352:1;122947:68:0;123025:12;123040:24;-1:-1:-1;;123040:22:0;;;:24::i;:::-;123123:28;;;;123074:34;123123:28;;;:14;:28;;;;;;;;;123111:41;;:11;:41;;;;;123178:13;;123025:39;;-1:-1:-1;123111:41:0;123178:13;;123170:21;;;;123162:65;;;;-1:-1:-1;;;123162:65:0;;12286:2:1;123162:65:0;;;12268:21:1;12325:2;12305:18;;;12298:30;12364:33;12344:18;;;12337:61;12415:18;;123162:65:0;12084:355:1;123162:65:0;123237:15;123255:23;-1:-1:-1;;123255:21:0;;;:23::i;:::-;70593:24;;;;:17;;;:24;;;;;123318:15;70593:37;;123237:41;-1:-1:-1;70427:22:0;;;;;;;;;;123484:7;123465:5;123406:145;;123439:12;123406:145;;;123505:36;:28;:5;:26;;;;:28::i;:36::-;123406:145;;;;;;:::i;:::-;;;;;;;;122820:738;;;;;122757:801;:::o;60447:115::-;60510:7;60536:19;60544:3;56062:18;;55980:107;74819:614;74998:5;74959:16;75014:413;71212:2;75034:1;:14;75014:413;;;75100:4;75085:11;;;75084:20;75066:15;75134:7;75095:1;75134:10;;;;;;;:::i;:::-;;;;;75118:26;;75162:7;75173:1;75162:12;75158:200;;75215:33;;;;;;13012:19:1;;;13047:12;;;13040:28;;;13084:12;;75215:33:0;;;;;;;;;;;;75205:44;;;;;;75194:55;;75158:200;;;75309:33;;;;;;13012:19:1;;;13047:12;;;13040:28;;;13084:12;;75309:33:0;;;;;;;;;;;;75299:44;;;;;;75288:55;;75158:200;-1:-1:-1;;75399:3:0;;75014:413;;;;74819:614;;;;;:::o;50841:327::-;52449:24;;;50912:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;50928:45;;-1:-1:-1;50968:5:0;50961:12;;50928:45;50983:23;;;;;;;:14;:23;;;;;;;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;51066:23;;;:30;;51030:15;:24;;;;;:33;;;;;;;;;:66;;;;51111:29;3284:74:1;;;51111:29:0;;3257:18:1;51111:29:0;;;;;;;-1:-1:-1;51157:4:0;50841:327;;;;:::o;60904:156::-;60978:7;61028:22;61032:3;61044:5;61028:3;:22::i;109000:808::-;109064:4;109397:13;;;;;;;109393:409;;;109451:7;:12;;109462:1;109451:12;:61;;;;-1:-1:-1;109506:4:0;97971:19;:23;109451:61;109426:166;;;;-1:-1:-1;;;109426:166:0;;13309:2:1;109426:166:0;;;13291:21:1;13348:2;13328:18;;;13321:30;13387:34;13367:18;;;13360:62;13458:16;13438:18;;;13431:44;13492:19;;109426:166:0;13107:410:1;109426:166:0;-1:-1:-1;109613:5:0;;109000:808;-1:-1:-1;109000:808:0:o;109393:409::-;109657:12;;:22;;;;:12;;:22;109649:81;;;;-1:-1:-1;;;109649:81:0;;13309:2:1;109649:81:0;;;13291:21:1;13348:2;13328:18;;;13321:30;13387:34;13367:18;;;13360:62;13458:16;13438:18;;;13431:44;13492:19;;109649:81:0;13107:410:1;109649:81:0;-1:-1:-1;109744:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;109000:808:0:o;109393:409::-;109000:808;;;:::o;115751:108::-;108411:13;;;;;;;108403:69;;;;-1:-1:-1;;;108403:69:0;;13724:2:1;108403:69:0;;;13706:21:1;13763:2;13743:18;;;13736:30;13802:34;13782:18;;;13775:62;13873:13;13853:18;;;13846:41;13904:19;;108403:69:0;13522:407:1;108403:69:0;115826:26:::1;:24;:26::i;83280:126::-:0;83347:7;83373:26;:8;80868:4;83373:12;:26::i;83530:305::-;83609:7;83590:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;83647:181:::1;83673:8;83699:35;83711:8;83721:12;83699:11;:35::i;:::-;83752:33;83764:8;83774:10;83752:11;:33::i;:::-;80924:12;83647:8;:181::i;:::-;83628:200;;81152:1;83530:305:::0;;;;:::o;87132:151::-;87208:6;87190:7;86212:37;80924:12;80917:20;-1:-1:-1;;86212:16:0;;;;:37::i;:::-;-1:-1:-1;87240:35:0::1;-1:-1:-1::0;;87240:17:0;::::1;85891:1;87273;87240:17;:35::i;87733:161::-:0;87814:6;87796:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87846:40:0::1;-1:-1:-1::0;;87846:17:0;::::1;86043:2;87884:1;87846:17;:40::i;22455:290::-:0;22511:14;22537:12;22552;22556:7;15386:3;15382:17;2670:26;15378:29;;15059:364;22552:12;22537:27;;;;22574:12;22589;22593:7;16492:2;16488:16;2670:26;16484:28;;16246:282;22589:12;22574:27;;22708:21;;;;22455:290;-1:-1:-1;;;22455:290:0:o;70963:182::-;71034:4;71057:36;;;;;:81;;-1:-1:-1;;69284:1:0;71097:41;;;70963:182::o;88171:174::-;88258:6;88240:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;88290:47:0::1;-1:-1:-1::0;;88290:17:0;::::1;86158:2;88335:1;88290:17;:47::i;83957:299::-:0;84034:7;84015:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;84072:177:::1;84098:8;84124:33;84136:8;84146:10;84124:11;:33::i;:::-;84175;84187:8;84197:10;84175:11;:33::i;:::-;80987:10;83647:8;:181::i;87960:147::-:0;88039:7;88021;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;88065:35:0::1;-1:-1:-1::0;;88065:13:0;::::1;86096:2;88097;88065:13;:35::i;130676:643::-:0;130751:17;130853:41;;;130849:464;;-1:-1:-1;;131156:15:0;;;;;109000:808::o;130849:464::-;131291:10;131264:38;80154:127;87527:149;87602:6;87584:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87634:34:0::1;-1:-1:-1::0;;87634:17:0;::::1;85988:2;87666:1;87634:17;:34::i;87335:141::-:0;87411:7;87393;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87437:32:0::1;-1:-1:-1::0;;87437:13:0;::::1;85940:1;87466:2;87437:13;:32::i;84378:190::-:0;84455:7;84436:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;84481:80:::1;84490:8;84500:33;84512:8;84522:10;84500:11;:33::i;:::-;16492:2:::0;16488:16;;;2670:26;16484:28;81048:10:::1;83647:8;:181::i;28308:632::-:0;28363:16;28391:11;28412:12;28427;28431:7;16492:2;16488:16;2670:26;16484:28;;16246:282;28427:12;28412:27;;;;28549:4;28543:11;28536:18;;28604:3;28597:10;;28650:33;28663:7;28672:3;28678:4;28672:10;28650:12;:33::i;:::-;-1:-1:-1;28807:14:0;;;28823:4;28803:25;28797:4;28790:39;28870:17;;28308:632;;-1:-1:-1;28308:632:0:o;70462:175::-;70593:24;;;;:17;;;;:24;;;;;:37;70462:175::o;61600:257::-;61663:16;61691:22;61716:19;61724:3;61716:7;:19::i;112878:187::-;112970:6;;;;112986:17;;;;;;;;;;;113018:40;;112970:6;;;112986:17;112970:6;;113018:40;;112951:16;;113018:40;112941:124;112878:187;:::o;47552:470::-;47652:16;;47707:19;:12;47652:16;47707;:19::i;:::-;47699:27;-1:-1:-1;32963:2:0;2670:26;16492:2;16488:16;;;16484:28;34217:37;47736:52;;;;-1:-1:-1;;;47736:52:0;;14136:2:1;47736:52:0;;;14118:21:1;14175:2;14155:18;;;14148:30;14214:20;14194:18;;;14187:48;14252:18;;47736:52:0;13934:342:1;47736:52:0;47809:115;47841:23;-1:-1:-1;;47841:21:0;;;:23::i;:::-;47878:36;:28;-1:-1:-1;;47878:26:0;;;:28::i;:36::-;47809:18;:115::i;:::-;47798:126;-1:-1:-1;47942:46:0;47952:25;-1:-1:-1;;47952:23:0;;;:25::i;:::-;52449:24;;52426:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;;;52342:152;47942:46;47934:81;;;;-1:-1:-1;;;47934:81:0;;14483:2:1;47934:81:0;;;14465:21:1;14522:2;14502:18;;;14495:30;14561:24;14541:18;;;14534:52;14603:18;;47934:81:0;14281:346:1;47934:81:0;47552:470;;;:::o;34358:143::-;34423:6;34455:38;-1:-1:-1;;34455:15:0;;34423:6;34491:1;34455:15;:38::i;34615:136::-;34679:6;34711:32;-1:-1:-1;;34711:15:0;;32857:1;;34711:15;:32::i;34844:124::-;34907:7;34933:28;-1:-1:-1;;34933:11:0;;32904:1;34958:2;34933:11;:28::i;35312:172::-;35380:7;35406:71;32963:2;35436:37;32963:2;16492;16488:16;;;2670:26;16484:28;35436:37;:::i;:::-;-1:-1:-1;;35406:11:0;;;:71;35475:1;35406:11;:71::i;56429:118::-;56496:7;56522:3;:11;;56534:5;56522:18;;;;;;;;:::i;:::-;;;;;;;;;56515:25;;56429:118;;;;:::o;111457:111::-;108411:13;;;;;;;108403:69;;;;-1:-1:-1;;;108403:69:0;;13724:2:1;108403:69:0;;;13706:21:1;13763:2;13743:18;;;13736:30;13802:34;13782:18;;;13775:62;13873:13;13853:18;;;13846:41;13904:19;;108403:69:0;13522:407:1;108403:69:0;111529:32:::1;110644:10:::0;111529:18:::1;:32::i;13655:359::-:0;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;:::-;13974:33;13655:359;-1:-1:-1;;;;;13655:359:0:o;10073:578::-;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;15129:31:1;10385:186:0;;;15117:44:1;15180:66;15284:3;15280:16;;;15276:25;;15262:12;;;15255:47;15332:15;15318:12;;;15311:37;15382:16;;;15378:25;15364:12;;;15357:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;15420:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;-1:-1:-1;;;10599:11:0;;;;;;;;:::i;10170:451::-;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;85090:164::-;85164:7;85190:57;81794:1;85217:5;85209:14;;;;;;;;:::i;:::-;:26;;;;:::i;:::-;-1:-1:-1;;85190:18:0;;;81794:1;85190:18;:57::i;84805:218::-;84946:7;84972:44;84987:5;84994:11;84987:5;84994:3;:11;:::i;:::-;-1:-1:-1;;84972:14:0;;;:44;85007:8;84972:14;:44::i;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;-1:-1:-1;;;20263:76:0;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;-1:-1:-1;;;20359:83:0;;16545:2:1;20359:83:0;;;16527:21:1;16584:2;16564:18;;;16557:30;16623:34;16603:18;;;16596:62;16694:28;16674:18;;;16667:56;16740:19;;20359:83:0;16343:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;27036:902::-;27114:15;-1:-1:-1;;7972:15:0;;;;27141:69;;;;-1:-1:-1;;;27141:69:0;;16972:2:1;27141:69:0;;;16954:21:1;17011:2;16991:18;;;16984:30;17050:34;17030:18;;;17023:62;17121:10;17101:18;;;17094:38;17149:19;;27141:69:0;16770:404:1;27141:69:0;27228:16;27236:7;27228;:16::i;:::-;27220:72;;;;-1:-1:-1;;;27220:72:0;;17381:2:1;27220:72:0;;;17363:21:1;17420:2;17400:18;;;17393:30;17459:34;17439:18;;;17432:62;17530:13;17510:18;;;17503:41;17561:19;;27220:72:0;17179:407:1;27220:72:0;27302:12;27317;27321:7;16492:2;16488:16;2670:26;16484:28;;16246:282;27317:12;27302:27;;;;27339:15;27357:12;27361:7;15386:3;15382:17;2670:26;15378:29;;15059:364;27357:12;27339:30;;;;27380:11;27501:4;27495:11;27488:18;;27588:7;27583:3;27580:16;27577:94;;;27628:4;27622;27615:18;27577:94;27843:4;27834:7;27828:4;27819:7;27816:1;27809:5;27798:50;27794:55;27879:52;27900:15;27907:7;14417:3;14413:17;;14206:268;27900:15;12061:27;12065:2;12061:27;;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;;11811:446;27879:52;27869:62;27036:902;-1:-1:-1;;;;;;27036:902:0:o;57087:109::-;57143:16;57178:3;:11;;57171:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57087:109;;;:::o;35074:155::-;35137:7;35163:59;-1:-1:-1;;35163:11:0;;35137:7;32963:2;35137:7;35163:11;:59::i;46716:285::-;46826:14;;46873;-1:-1:-1;;46873:12:0;;;:14::i;:::-;46856:31;;46906:36;46935:6;45309:58;;19348:66:1;45309:58:0;;;19336:79:1;19431:12;;;19424:28;;;45179:7:0;;19468:12:1;;45309:58:0;;;;;;;;;;;;45299:69;;;;;;45292:76;;45110:265;;;;46906:36;46897:45;;46961:33;46975:6;46983:10;46961:13;:33::i;17129:399::-;17268:7;17287:12;17302;17306:7;15386:3;15382:17;2670:26;15378:29;;15059:364;17302:12;17287:27;;;;17398:12;17402:7;17398:3;:12::i;:::-;17391:4;17375:13;17382:6;17375:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17371:77;;;-1:-1:-1;;17426:11:0;;;;;17371:77;17465:13;17472:6;17465:4;:13;:::i;:::-;17458:20;;17495:26;17501:7;17495:26;;17510:4;17516;12796:462;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;-1:-1:-1;;12065:2:0;12061:27;;;12135:17;;;;12127:26;;;12199:17;12195:2;12191:26;;12796:462::o;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19061:33;;;19244:1;19306;19386;19448;19130:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19104:391;;18926:576;;;;18761:741;;;;;;:::o;8645:333::-;8702:8;8726:15;8733:7;14417:3;14413:17;;14206:268;8726:15;:31;;8745:12;8726:31;8722:74;;-1:-1:-1;8780:5:0;;8645:333;-1:-1:-1;8645:333:0:o;8722:74::-;8805:12;8820;8824:7;8820:3;:12::i;:::-;8955:4;8949:11;-1:-1:-1;8936:26:0;;8645:333;-1:-1:-1;;;8645:333:0:o;41406:227::-;41484:7;41504:17;41523:18;41545:27;41556:4;41562:9;41545:10;:27::i;:::-;41503:69;;;;41582:18;41594:5;41582:11;:18::i;16702:147::-;16755:7;16820:12;16824:7;16492:2;16488:16;2670:26;16484:28;;16246:282;16820:12;16805;16809:7;15386:3;15382:17;2670:26;15378:29;;15059:364;16805:12;:27;16798:34;;;;16702:147;;;:::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;39341:1279::-;39422:7;39431:12;39652:9;:16;39672:2;39652:22;39648:966;;39941:4;39926:20;;39920:27;39990:4;39975:20;;39969:27;40047:4;40032:20;;40026:27;39690:9;40018:36;40088:25;40099:4;40018:36;39920:27;39969;40088:10;:25::i;:::-;40081:32;;;;;;;;;39648:966;40134:9;:16;40154:2;40134:22;40130:484;;40403:4;40388:20;;40382:27;40453:4;40438:20;;40432:27;40493:23;40504:4;40382:27;40432;40493:10;:23::i;:::-;40486:30;;;;;;;;40130:484;-1:-1:-1;40563:1:0;;-1:-1:-1;40567:35:0;40130:484;39341:1279;;;;;:::o;37646:631::-;37723:20;37714:5;:29;;;;;;;;:::i;:::-;;37710:561;;37646:631;:::o;37710:561::-;37819:29;37810:5;:38;;;;;;;;:::i;:::-;;37806:465;;37864:34;;-1:-1:-1;;;37864:34:0;;19693:2:1;37864:34:0;;;19675:21:1;19732:2;19712:18;;;19705:30;19771:26;19751:18;;;19744:54;19815:18;;37864:34:0;19491:348:1;37806:465:0;37928:35;37919:5;:44;;;;;;;;:::i;:::-;;37915:356;;37979:41;;-1:-1:-1;;;37979:41:0;;20046:2:1;37979:41:0;;;20028:21:1;20085:2;20065:18;;;20058:30;20124:33;20104:18;;;20097:61;20175:18;;37979:41:0;19844:355:1;37915:356:0;38050:30;38041:5;:39;;;;;;;;:::i;:::-;;38037:234;;38096:44;;-1:-1:-1;;;38096:44:0;;20406:2:1;38096:44:0;;;20388:21:1;20445:2;20425:18;;;20418:30;20484:34;20464:18;;;20457:62;20555:4;20535:18;;;20528:32;20577:19;;38096:44:0;20204:398:1;38037:234:0;38170:30;38161:5;:39;;;;;;;;:::i;:::-;;38157:114;;38216:44;;-1:-1:-1;;;38216:44:0;;20809:2:1;38216:44:0;;;20791:21:1;20848:2;20828:18;;;20821:30;20887:34;20867:18;;;20860:62;20958:4;20938:18;;;20931:32;20980:19;;38216:44:0;20607:398:1;2943:1393:0;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;42814:1603::-;42940:7;;43864:66;43851:79;;43847:161;;;-1:-1:-1;43962:1:0;;-1:-1:-1;43966:30:0;43946:51;;43847:161;44021:1;:7;;44026:2;44021:7;;:18;;;;;44032:1;:7;;44037:2;44032:7;;44021:18;44017:100;;;-1:-1:-1;44071:1:0;;-1:-1:-1;44075:30:0;44055:51;;44017:100;44228:24;;;44211:14;44228:24;;;;;;;;;21237:25:1;;;21310:4;21298:17;;21278:18;;;21271:45;;;;21332:18;;;21325:34;;;21375:18;;;21368:34;;;44228:24:0;;21209:19:1;;44228:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44228:24:0;;;;;;-1:-1:-1;;44266:20:0;;;44262:101;;44318:1;44322:29;44302:50;;;;;;;44262:101;44381:6;-1:-1:-1;44389:20:0;;-1:-1:-1;42814:1603:0;;;;;;;;:::o;41887:336::-;41997:7;;42055:66;42042:80;;41997:7;42148:25;42164:3;42149:18;;;42171:2;42148:25;:::i;:::-;42132:42;;42191:25;42202:4;42208:1;42211;42214;42191:10;:25::i;:::-;42184:32;;;;;;41887:336;;;;;;:::o;14:163:1:-;81:20;;141:10;130:22;;120:33;;110:61;;167:1;164;157:12;182:324;257:6;265;273;326:2;314:9;305:7;301:23;297:32;294:52;;;342:1;339;332:12;294:52;365:28;383:9;365:28;:::i;:::-;355:38;;412:37;445:2;434:9;430:18;412:37;:::i;:::-;402:47;;496:2;485:9;481:18;468:32;458:42;;182:324;;;;;:::o;885:184::-;937:77;934:1;927:88;1034:4;1031:1;1024:15;1058:4;1055:1;1048:15;1074:777;1116:5;1169:3;1162:4;1154:6;1150:17;1146:27;1136:55;;1187:1;1184;1177:12;1136:55;1223:6;1210:20;1249:18;1286:2;1282;1279:10;1276:36;;;1292:18;;:::i;:::-;1426:2;1420:9;1488:4;1480:13;;1331:66;1476:22;;;1500:2;1472:31;1468:40;1456:53;;;1524:18;;;1544:22;;;1521:46;1518:72;;;1570:18;;:::i;:::-;1610:10;1606:2;1599:22;1645:2;1637:6;1630:18;1691:3;1684:4;1679:2;1671:6;1667:15;1663:26;1660:35;1657:55;;;1708:1;1705;1698:12;1657:55;1772:2;1765:4;1757:6;1753:17;1746:4;1738:6;1734:17;1721:54;1819:1;1812:4;1807:2;1799:6;1795:15;1791:26;1784:37;1839:6;1830:15;;;;;;1074:777;;;;:::o;1856:609::-;1976:6;1984;1992;2000;2053:4;2041:9;2032:7;2028:23;2024:34;2021:54;;;2071:1;2068;2061:12;2021:54;2094:28;2112:9;2094:28;:::i;:::-;2084:38;;2173:2;2162:9;2158:18;2145:32;2200:18;2192:6;2189:30;2186:50;;;2232:1;2229;2222:12;2186:50;2255:49;2296:7;2287:6;2276:9;2272:22;2255:49;:::i;:::-;2245:59;;;2338:4;2327:9;2323:20;2362:7;2358:2;2355:15;2352:35;;;2383:1;2380;2373:12;2352:35;1856:609;;;;-1:-1:-1;;;2421:2:1;2406:18;;;;;2443:16;;;1856:609::o;2470:154::-;2556:42;2549:5;2545:54;2538:5;2535:65;2525:93;;2614:1;2611;2604:12;2629:319;2696:6;2704;2757:2;2745:9;2736:7;2732:23;2728:32;2725:52;;;2773:1;2770;2763:12;2725:52;2796:28;2814:9;2796:28;:::i;:::-;2786:38;;2874:2;2863:9;2859:18;2846:32;2887:31;2912:5;2887:31;:::i;:::-;2937:5;2927:15;;;2629:319;;;;;:::o;2953:180::-;3012:6;3065:2;3053:9;3044:7;3040:23;3036:32;3033:52;;;3081:1;3078;3071:12;3033:52;-1:-1:-1;3104:23:1;;2953:180;-1:-1:-1;2953:180:1:o;3369:252::-;3436:6;3444;3497:2;3485:9;3476:7;3472:23;3468:32;3465:52;;;3513:1;3510;3503:12;3465:52;3536:28;3554:9;3536:28;:::i;:::-;3526:38;3611:2;3596:18;;;;3583:32;;-1:-1:-1;;;3369:252:1:o;4005:320::-;4073:6;4126:2;4114:9;4105:7;4101:23;4097:32;4094:52;;;4142:1;4139;4132:12;4094:52;4182:9;4169:23;4215:18;4207:6;4204:30;4201:50;;;4247:1;4244;4237:12;4201:50;4270:49;4311:7;4302:6;4291:9;4287:22;4270:49;:::i;4330:320::-;4406:6;4414;4422;4475:2;4463:9;4454:7;4450:23;4446:32;4443:52;;;4491:1;4488;4481:12;4443:52;4514:28;4532:9;4514:28;:::i;:::-;4504:38;4589:2;4574:18;;4561:32;;-1:-1:-1;4640:2:1;4625:18;;;4612:32;;4330:320;-1:-1:-1;;;4330:320:1:o;4655:681::-;4826:2;4878:21;;;4948:13;;4851:18;;;4970:22;;;4797:4;;4826:2;5049:15;;;;5023:2;5008:18;;;4797:4;5092:218;5106:6;5103:1;5100:13;5092:218;;;5171:13;;5186:42;5167:62;5155:75;;5285:15;;;;5250:12;;;;5128:1;5121:9;5092:218;;;-1:-1:-1;5327:3:1;;4655:681;-1:-1:-1;;;;;;4655:681:1:o;5341:184::-;5399:6;5452:2;5440:9;5431:7;5427:23;5423:32;5420:52;;;5468:1;5465;5458:12;5420:52;5491:28;5509:9;5491:28;:::i;5530:272::-;5614:6;5667:2;5655:9;5646:7;5642:23;5638:32;5635:52;;;5683:1;5680;5673:12;5635:52;5722:9;5709:23;5741:31;5766:5;5741:31;:::i;6504:184::-;6556:77;6553:1;6546:88;6653:4;6650:1;6643:15;6677:4;6674:1;6667:15;6693:128;6733:3;6764:1;6760:6;6757:1;6754:13;6751:39;;;6770:18;;:::i;:::-;-1:-1:-1;6806:9:1;;6693:128::o;6826:184::-;6878:77;6875:1;6868:88;6975:4;6972:1;6965:15;6999:4;6996:1;6989:15;9980:530;10021:3;10059:5;10053:12;10086:6;10081:3;10074:19;10111:1;10121:162;10135:6;10132:1;10129:13;10121:162;;;10197:4;10253:13;;;10249:22;;10243:29;10225:11;;;10221:20;;10214:59;10150:12;10121:162;;;10301:6;10298:1;10295:13;10292:87;;;10367:1;10360:4;10351:6;10346:3;10342:16;10338:27;10331:38;10292:87;-1:-1:-1;10424:2:1;10412:15;10429:66;10408:88;10399:98;;;;10499:4;10395:109;;9980:530;-1:-1:-1;;9980:530:1:o;10515:547::-;10733:4;10762:10;10811:2;10803:6;10799:15;10788:9;10781:34;10863:2;10855:6;10851:15;10846:2;10835:9;10831:18;10824:43;;10903:6;10898:2;10887:9;10883:18;10876:34;10946:6;10941:2;10930:9;10926:18;10919:34;10990:3;10984;10973:9;10969:19;10962:32;11011:45;11051:3;11040:9;11036:19;11028:6;11011:45;:::i;:::-;11003:53;10515:547;-1:-1:-1;;;;;;;10515:547:1:o;12444:217::-;12591:2;12580:9;12573:21;12554:4;12611:44;12651:2;12640:9;12636:18;12628:6;12611:44;:::i;12666:184::-;12718:77;12715:1;12708:88;12815:4;12812:1;12805:15;12839:4;12836:1;12829:15;14632:125;14672:4;14700:1;14697;14694:8;14691:34;;;14705:18;;:::i;:::-;-1:-1:-1;14742:9:1;;14632:125::o;15667:228::-;15707:7;15833:1;15765:66;15761:74;15758:1;15755:81;15750:1;15743:9;15736:17;15732:105;15729:131;;;15840:18;;:::i;:::-;-1:-1:-1;15880:9:1;;15667:228::o;15900:195::-;15938:4;15975;15972:1;15968:12;16007:4;16004:1;16000:12;16032:3;16027;16024:12;16021:38;;;16039:18;;:::i;:::-;16076:13;;;15900:195;-1:-1:-1;;;15900:195:1:o;16100:238::-;16138:7;16178:4;16175:1;16171:12;16210:4;16207:1;16203:12;16270:3;16264:4;16260:14;16255:3;16252:23;16245:3;16238:11;16231:19;16227:49;16224:75;;;16279:18;;:::i;:::-;16319:13;;16100:238;-1:-1:-1;;;16100:238:1:o;17710:1391::-;18432:34;18420:47;;18497:23;18492:2;18483:12;;18476:45;18540:66;18644:3;18640:16;;;18636:25;;18631:2;18622:12;;18615:47;18681:17;18723:2;18714:12;;18707:24;;;18765:16;;;18761:25;;18756:2;18747:12;;18740:47;18817:34;18812:2;18803:12;;18796:56;18883:3;18877;18868:13;;18861:26;18922:16;;;18918:25;;18912:3;18903:13;;18896:48;18969:3;18960:13;;18953:25;19013:16;;;19009:25;19003:3;18994:13;;18987:48;17668:3;19090;19081:13;;17656:16;-1:-1:-1;17688:11:1;;;19051:44;17591:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"AttestationAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"Process","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"previousConfirmAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newConfirmAt","type":"uint256"}],"name":"SetConfirmation","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"acceptableRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"activeReplicaConfirmedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_messageId","type":"bytes32"}],"name":"activeReplicaMessageStatus","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"}],"name":"activeReplicaNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"process","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"prove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"proveAndProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"uint256","name":"_confirmAt","type":"uint256"}],"name":"setConfirmation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"submitAttestation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"events":{"Process(uint32,bytes32)":{"notice":"Emitted when message is processed"},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"notice":"Emitted when a root's confirmation is modified by governance"}},"kind":"user","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"notice":"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed"},"initialize(uint32,address)":{"notice":"Initialize the replica"},"process(bytes)":{"notice":"Given formatted message, attempts to dispatch message payload to end recipient."},"prove(uint32,bytes,bytes32[32],uint256)":{"notice":"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf."},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"notice":"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message."},"setConfirmation(uint32,bytes32,uint256)":{"notice":"Set confirmAt for a given root"},"setUpdater(uint32,address)":{"notice":"Set Updater role"},"submitAttestation(bytes)":{"notice":"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event."}},"notice":"Track root updates on Home, prove and dispatch messages to end recipients.","version":1},"developerDoc":{"events":{"Process(uint32,bytes32)":{"params":{"messageHash":"The keccak256 hash of the message that was processed"}},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"params":{"newConfirmAt":"The new value of confirmAt","previousConfirmAt":"The previous value of confirmAt","root":"The root for which confirmAt has been set"}}},"kind":"dev","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"params":{"_root":"the Merkle root, submitted in an update, to check"},"returns":{"_0":"TRUE iff root has been submitted \u0026 timeout has expired"}},"initialize(uint32,address)":{"details":"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer","params":{"_remoteDomain":"The domain of the Home contract this follows","_updater":"The EVM id of the updater"}},"owner()":{"details":"Returns the address of the current owner."},"process(bytes)":{"details":"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.","params":{"_message":"Formatted message"}},"prove(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message","_proof":"Merkle proof of inclusion for leaf"},"returns":{"_0":"Returns true if proof was valid and `prove` call succeeded*"}},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if `prove` call returns false","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message (refer to Message library)","_proof":"Merkle proof of inclusion for message's leaf"}},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setConfirmation(uint32,bytes32,uint256)":{"details":"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)","params":{"_confirmAt":"The new confirmation time. Set to 0 to \"delete\" a root.","_root":"The root for which to modify confirm time"}},"setUpdater(uint32,address)":{"details":"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)","params":{"_updater":"New Updater"}},"submitAttestation(bytes)":{"details":"Reverts if update doesn't build off latest committedRoot or if signature is invalid.","params":{"_attestation":"Attestation data and signature"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"title":"ReplicaManager","version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"AttestationAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Process(uint32,bytes32)\":{\"params\":{\"messageHash\":\"The keccak256 hash of the message that was processed\"}},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"params\":{\"newConfirmAt\":\"The new value of confirmAt\",\"previousConfirmAt\":\"The previous value of confirmAt\",\"root\":\"The root for which confirmAt has been set\"}}},\"kind\":\"dev\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"params\":{\"_root\":\"the Merkle root, submitted in an update, to check\"},\"returns\":{\"_0\":\"TRUE iff root has been submitted \u0026 timeout has expired\"}},\"initialize(uint32,address)\":{\"details\":\"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer\",\"params\":{\"_remoteDomain\":\"The domain of the Home contract this follows\",\"_updater\":\"The EVM id of the updater\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"process(bytes)\":{\"details\":\"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.\",\"params\":{\"_message\":\"Formatted message\"}},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message\",\"_proof\":\"Merkle proof of inclusion for leaf\"},\"returns\":{\"_0\":\"Returns true if proof was valid and `prove` call succeeded*\"}},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if `prove` call returns false\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message (refer to Message library)\",\"_proof\":\"Merkle proof of inclusion for message's leaf\"}},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"details\":\"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)\",\"params\":{\"_confirmAt\":\"The new confirmation time. Set to 0 to \\\"delete\\\" a root.\",\"_root\":\"The root for which to modify confirm time\"}},\"setUpdater(uint32,address)\":{\"details\":\"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)\",\"params\":{\"_updater\":\"New Updater\"}},\"submitAttestation(bytes)\":{\"details\":\"Reverts if update doesn't build off latest committedRoot or if signature is invalid.\",\"params\":{\"_attestation\":\"Attestation data and signature\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"title\":\"ReplicaManager\",\"version\":1},\"userdoc\":{\"events\":{\"Process(uint32,bytes32)\":{\"notice\":\"Emitted when message is processed\"},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"notice\":\"Emitted when a root's confirmation is modified by governance\"}},\"kind\":\"user\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"notice\":\"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed\"},\"initialize(uint32,address)\":{\"notice\":\"Initialize the replica\"},\"process(bytes)\":{\"notice\":\"Given formatted message, attempts to dispatch message payload to end recipient.\"},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf.\"},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message.\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"notice\":\"Set confirmAt for a given root\"},\"setUpdater(uint32,address)\":{\"notice\":\"Set Updater role\"},\"submitAttestation(bytes)\":{\"notice\":\"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event.\"}},\"notice\":\"Track root updates on Home, prove and dispatch messages to end recipients.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"ReplicaManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74","acceptableRoot(uint32,uint32,bytes32)":"15a046aa","activeReplicaConfirmedAt(uint32,bytes32)":"7dfdba28","activeReplicaMessageStatus(uint32,bytes32)":"63415514","activeReplicaNonce(uint32)":"b65672d3","allGuards()":"9fe03fa2","getGuard(uint256)":"629ddf69","guardsAmount()":"246c2449","initialize(uint32,address)":"8624c35c","localDomain()":"8d3638f4","owner()":"8da5cb5b","process(bytes)":"928bc4b2","prove(uint32,bytes,bytes32[32],uint256)":"4f63be3f","proveAndProcess(uint32,bytes,bytes32[32],uint256)":"68705275","renounceOwnership()":"715018a6","setConfirmation(uint32,bytes32,uint256)":"9df7d36d","setSystemMessenger(address)":"b7bc563e","setUpdater(uint32,address)":"61bc3111","submitAttestation(bytes)":"f646a512","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManager.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ee25f1552b8abf2a2770afb33509113630c944d4976a615272a0b52af2fd064d64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ee25f1552b8abf2a2770afb33509113630c944d4976a615272a0b52af2fd064d64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"35580:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;35580:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"35580:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:SystemContract":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"SystemContract\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManager.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122020d737f94707ef513e072e66cdde5c16f0cac8dec58a05880ca533fed1e7795964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122020d737f94707ef513e072e66cdde5c16f0cac8dec58a05880ca533fed1e7795964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"91564:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;91564:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"91564:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220925ac4f818c4109946a24ff7cef9ce6373c0521e82f7ff2d0cf8c5d2d771174064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220925ac4f818c4109946a24ff7cef9ce6373c0521e82f7ff2d0cf8c5d2d771174064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"88563:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;88563:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"88563:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f937ba1ec907990c38c04e13fdac240c223d1b04b8e825a7cfd351cfe029ae6864736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f937ba1ec907990c38c04e13fdac240c223d1b04b8e825a7cfd351cfe029ae6864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"79173:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;79173:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"79173:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManager.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220802d542f548dd16236b5168df2902ecfe93508d03a00eecc215cf533c4eeebad64736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220802d542f548dd16236b5168df2902ecfe93508d03a00eecc215cf533c4eeebad64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/ReplicaManager.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220e6b05536f202394e029bd7cf9e31164cadcf895ceb7cb5b417fbb857ee50f3d664736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220e6b05536f202394e029bd7cf9e31164cadcf895ceb7cb5b417fbb857ee50f3d664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title ReplicaManager\n * @notice Track root updates on Home,\n * prove and dispatch messages to end recipients.\n */\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"68086:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"68086:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68110:33;;68142:1;68110:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;68110:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManager.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManager.sol\":{\"keccak256\":\"0xe87820571ac1dfb74efc6485950f6fdd33a3a82e7738c6d7f156161de1864b24\",\"urls\":[\"bzz-raw://ee5cfbe44039063aea36bd14cd9b637c405a485822bc2197d599226f4c2cf1ab\",\"dweb:/ipfs/QmeSrGqcgHT5KBGBCaZctnrH6d5kPUb7y9eAqtXbnNxhM8\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file diff --git a/core/contracts/test/headerharness/headerharness.abigen.go b/core/contracts/test/headerharness/headerharness.abigen.go index 478e132031..d910449731 100644 --- a/core/contracts/test/headerharness/headerharness.abigen.go +++ b/core/contracts/test/headerharness/headerharness.abigen.go @@ -31,7 +31,7 @@ var ( // HeaderMetaData contains all meta data concerning the Header contract. var HeaderMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204a9b2e41355d41224f05659e726f6071ceb5e33ba5b57e205203c404e121032a64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220340f846ad6fee7367710f26f24839fc8304fff32c7eb1785147ddb38a4901dae64736f6c634300080d0033", } // HeaderABI is the input ABI used to generate the binding from. @@ -221,7 +221,7 @@ var HeaderHarnessMetaData = &bind.MetaData{ "418fad6d": "recipient(bytes29)", "a0d41e58": "sender(bytes29)", }, - Bin: "0x608060405234801561001057600080fd5b50610d2e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80635cf682c611610097578063a9f877ad11610066578063a9f877ad146101b6578063ac124002146101c9578063ae2ab89f1461027e578063d2c4428a1461029157600080fd5b80635cf682c6146101735780639253ae7714610189578063a0d41e581461019c578063a2ce1f35146101af57600080fd5b80634155c3d5116100d35780634155c3d51461013f578063418fad6d14610146578063569e1eaf1461015957806358c8a98f1461016057600080fd5b806307fd670d146100fa57806311cd4add14610110578063320bfc4414610138575b600080fd5b60065b6040519081526020015b60405180910390f35b61012361011e366004610b42565b610298565b60405163ffffffff9091168152602001610107565b60026100fd565b604e6100fd565b6100fd610154366004610b42565b6102a9565b60266100fd565b61012361016e366004610b42565b6102b4565b60015b60405161ffff9091168152602001610107565b610123610197366004610b42565b6102bf565b6100fd6101aa366004610b42565b6102ca565b602e6100fd565b6101236101c4366004610b42565b6102d5565b6102716101d7366004610b81565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e098891b81166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281518082036052018152607290910190915290565b6040516101079190610c52565b61017661028c366004610b42565b6102e0565b602a6100fd565b60006102a3826102eb565b92915050565b60006102a38261031e565b60006102a38261033f565b60006102a382610360565b60006102a382610381565b60006102a3826103a2565b60006102a3826103c3565b60008161030160015b62ffffff198316906103e4565b5061031562ffffff198416602a6004610508565b91505b50919050565b60008161032b60016102f4565b5061031562ffffff198416602e602061053a565b60008161034c60016102f4565b5061031562ffffff19841660266004610508565b60008161036d60016102f4565b5061031562ffffff198416604e6004610508565b60008161038e60016102f4565b5061031562ffffff1984166006602061053a565b6000816103af60016102f4565b5061031562ffffff19841660026004610508565b6000816103d060016102f4565b5061031562ffffff19841660006002610508565b60006103f0838361072c565b61050157600061040f6104038560d81c90565b64ffffffffff1661074f565b91505060006104248464ffffffffff1661074f565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60405180910390fd5b5090919050565b6000610515826020610c94565b610520906008610cb7565b60ff1661052e85858561053a565b901c90505b9392505050565b60008160ff1660000361054f57506000610533565b6105678460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661058260ff841685610ce0565b1115610614576105e16105a38560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166105c98660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16610839565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60208260ff1611156106a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104f8565b6008820260006106c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b60008164ffffffffff166107408460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156107c257600061076e826008610cb7565b60ff1685901c905061077f816109c9565b61ffff16841793508160ff1660101461079a57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610755565b50600f5b60ff8160ff1610156108335760006107df826008610cb7565b60ff1685901c90506107f0816109c9565b61ffff16831792508160ff1660001461080b57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016107c6565b50915091565b606060006108468661074f565b91505060006108548661074f565b91505060006108628661074f565b91505060006108708661074f565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b60006109db60048360ff16901c6109fb565b60ff1661ffff919091161760081b6109f2826109fb565b60ff1617919050565b600060f08083179060ff82169003610a165750603092915050565b8060ff1660f103610a2a5750603192915050565b8060ff1660f203610a3e5750603292915050565b8060ff1660f303610a525750603392915050565b8060ff1660f403610a665750603492915050565b8060ff1660f503610a7a5750603592915050565b8060ff1660f603610a8e5750603692915050565b8060ff1660f703610aa25750603792915050565b8060ff1660f803610ab65750603892915050565b8060ff1660f903610aca5750603992915050565b8060ff1660fa03610ade5750606192915050565b8060ff1660fb03610af25750606292915050565b8060ff1660fc03610b065750606392915050565b8060ff1660fd03610b1a5750606492915050565b8060ff1660fe03610b2e5750606592915050565b8060ff1660ff036103185750606692915050565b600060208284031215610b5457600080fd5b813562ffffff198116811461053357600080fd5b803563ffffffff81168114610b7c57600080fd5b919050565b60008060008060008060c08789031215610b9a57600080fd5b610ba387610b68565b955060208701359450610bb860408801610b68565b9350610bc660608801610b68565b925060808701359150610bdb60a08801610b68565b90509295509295509295565b6000815180845260005b81811015610c0d57602081850181015186830182015201610bf1565b81811115610c1f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105336020830184610be7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff841680821015610cae57610cae610c65565b90039392505050565b600060ff821660ff84168160ff0481118215151615610cd857610cd8610c65565b029392505050565b60008219821115610cf357610cf3610c65565b50019056fea264697066735822122099b156599b724d59e20ed377892ee914db4ea70fb5a77a6143d26b044e5668fb64736f6c634300080d0033", + Bin: "0x608060405234801561001057600080fd5b50610d2e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80635cf682c611610097578063a9f877ad11610066578063a9f877ad146101b6578063ac124002146101c9578063ae2ab89f1461027e578063d2c4428a1461029157600080fd5b80635cf682c6146101735780639253ae7714610189578063a0d41e581461019c578063a2ce1f35146101af57600080fd5b80634155c3d5116100d35780634155c3d51461013f578063418fad6d14610146578063569e1eaf1461015957806358c8a98f1461016057600080fd5b806307fd670d146100fa57806311cd4add14610110578063320bfc4414610138575b600080fd5b60065b6040519081526020015b60405180910390f35b61012361011e366004610b42565b610298565b60405163ffffffff9091168152602001610107565b60026100fd565b604e6100fd565b6100fd610154366004610b42565b6102a9565b60266100fd565b61012361016e366004610b42565b6102b4565b60015b60405161ffff9091168152602001610107565b610123610197366004610b42565b6102bf565b6100fd6101aa366004610b42565b6102ca565b602e6100fd565b6101236101c4366004610b42565b6102d5565b6102716101d7366004610b81565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e098891b81166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281518082036052018152607290910190915290565b6040516101079190610c52565b61017661028c366004610b42565b6102e0565b602a6100fd565b60006102a3826102eb565b92915050565b60006102a38261031e565b60006102a38261033f565b60006102a382610360565b60006102a382610381565b60006102a3826103a2565b60006102a3826103c3565b60008161030160015b62ffffff198316906103e4565b5061031562ffffff198416602a6004610508565b91505b50919050565b60008161032b60016102f4565b5061031562ffffff198416602e602061053a565b60008161034c60016102f4565b5061031562ffffff19841660266004610508565b60008161036d60016102f4565b5061031562ffffff198416604e6004610508565b60008161038e60016102f4565b5061031562ffffff1984166006602061053a565b6000816103af60016102f4565b5061031562ffffff19841660026004610508565b6000816103d060016102f4565b5061031562ffffff19841660006002610508565b60006103f0838361072c565b61050157600061040f6104038560d81c90565b64ffffffffff1661074f565b91505060006104248464ffffffffff1661074f565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60405180910390fd5b5090919050565b6000610515826020610c94565b610520906008610cb7565b60ff1661052e85858561053a565b901c90505b9392505050565b60008160ff1660000361054f57506000610533565b6105678460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661058260ff841685610ce0565b1115610614576105e16105a38560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166105c98660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16610839565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60208260ff1611156106a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104f8565b6008820260006106c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b60008164ffffffffff166107408460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156107c257600061076e826008610cb7565b60ff1685901c905061077f816109c9565b61ffff16841793508160ff1660101461079a57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610755565b50600f5b60ff8160ff1610156108335760006107df826008610cb7565b60ff1685901c90506107f0816109c9565b61ffff16831792508160ff1660001461080b57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016107c6565b50915091565b606060006108468661074f565b91505060006108548661074f565b91505060006108628661074f565b91505060006108708661074f565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b60006109db60048360ff16901c6109fb565b60ff1661ffff919091161760081b6109f2826109fb565b60ff1617919050565b600060f08083179060ff82169003610a165750603092915050565b8060ff1660f103610a2a5750603192915050565b8060ff1660f203610a3e5750603292915050565b8060ff1660f303610a525750603392915050565b8060ff1660f403610a665750603492915050565b8060ff1660f503610a7a5750603592915050565b8060ff1660f603610a8e5750603692915050565b8060ff1660f703610aa25750603792915050565b8060ff1660f803610ab65750603892915050565b8060ff1660f903610aca5750603992915050565b8060ff1660fa03610ade5750606192915050565b8060ff1660fb03610af25750606292915050565b8060ff1660fc03610b065750606392915050565b8060ff1660fd03610b1a5750606492915050565b8060ff1660fe03610b2e5750606592915050565b8060ff1660ff036103185750606692915050565b600060208284031215610b5457600080fd5b813562ffffff198116811461053357600080fd5b803563ffffffff81168114610b7c57600080fd5b919050565b60008060008060008060c08789031215610b9a57600080fd5b610ba387610b68565b955060208701359450610bb860408801610b68565b9350610bc660608801610b68565b925060808701359150610bdb60a08801610b68565b90509295509295509295565b6000815180845260005b81811015610c0d57602081850181015186830182015201610bf1565b81811115610c1f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105336020830184610be7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff841680821015610cae57610cae610c65565b90039392505050565b600060ff821660ff84168160ff0481118215151615610cd857610cd8610c65565b029392505050565b60008219821115610cf357610cf3610c65565b50019056fea2646970667358221220a46e5ae0ecbe858653f5c1f2078791ef504340f562b34d0c41021648aaab650764736f6c634300080d0033", } // HeaderHarnessABI is the input ABI used to generate the binding from. @@ -863,7 +863,7 @@ func (_HeaderHarness *HeaderHarnessCallerSession) Sender(_header [29]byte) ([32] // MessageMetaData contains all meta data concerning the Message contract. var MessageMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b6c73bc0d6ab1fe8ea56cb2e3eefe470c06b44d4d68cc277c37ce9676ce6e0f664736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205de236cc79dd1a35910b8896839cd6cea3071d602ed924e656ddb553d444554c64736f6c634300080d0033", } // MessageABI is the input ABI used to generate the binding from. @@ -1036,7 +1036,7 @@ func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method s // TypeCastsMetaData contains all meta data concerning the TypeCasts contract. var TypeCastsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220da8acce1cdc21bb132761fab03293e69f28573630e8aab824a3b6aee2410d47164736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220be30b0ec5d51a8266770aec2af16b2b406e1b86ecb83c8ec4f55b83b1c563db164736f6c634300080d0033", } // TypeCastsABI is the input ABI used to generate the binding from. @@ -1212,7 +1212,7 @@ var TypedMemViewMetaData = &bind.MetaData{ Sigs: map[string]string{ "f26be3fc": "NULL()", }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122085ba6896a6f6b5ccc9a976dcfdb6a3e58a759dcaaad8fd8a23d7b5ab4f5f937664736f6c634300080d0033", + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220638f5e4bebb379c68231cb1f255621661becf1becd3d8c455549ffc24d5f3ab264736f6c634300080d0033", } // TypedMemViewABI is the input ABI used to generate the binding from. diff --git a/core/contracts/test/headerharness/headerharness.contractinfo.json b/core/contracts/test/headerharness/headerharness.contractinfo.json index fd2c57b415..4ef840f9a7 100644 --- a/core/contracts/test/headerharness/headerharness.contractinfo.json +++ b/core/contracts/test/headerharness/headerharness.contractinfo.json @@ -1 +1 @@ -{"solidity/HeaderHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204a9b2e41355d41224f05659e726f6071ceb5e33ba5b57e205203c404e121032a64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204a9b2e41355d41224f05659e726f6071ceb5e33ba5b57e205203c404e121032a64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return Header.formatHeader(_originDomain, _sender, _nonce, _destinationDomain, _recipient, _optimisticSeconds);\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33386:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33386:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33386:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x2cb76221c7acc178581b6d31566d309b1db38b4ef6e9037272d9b623d86315eb\",\"urls\":[\"bzz-raw://6d493a81dd7f7e24669dd157df510333ed97c4a00632a634d8232cafdcbb6199\",\"dweb:/ipfs/QmYYog547KTpsFFiP5RwfbL8hQ7SS3kPYpbFXf4RdmwpQc\"]}},\"version\":1}"},"hashes":{}},"solidity/HeaderHarness.sol:HeaderHarness":{"code":"0x608060405234801561001057600080fd5b50610d2e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80635cf682c611610097578063a9f877ad11610066578063a9f877ad146101b6578063ac124002146101c9578063ae2ab89f1461027e578063d2c4428a1461029157600080fd5b80635cf682c6146101735780639253ae7714610189578063a0d41e581461019c578063a2ce1f35146101af57600080fd5b80634155c3d5116100d35780634155c3d51461013f578063418fad6d14610146578063569e1eaf1461015957806358c8a98f1461016057600080fd5b806307fd670d146100fa57806311cd4add14610110578063320bfc4414610138575b600080fd5b60065b6040519081526020015b60405180910390f35b61012361011e366004610b42565b610298565b60405163ffffffff9091168152602001610107565b60026100fd565b604e6100fd565b6100fd610154366004610b42565b6102a9565b60266100fd565b61012361016e366004610b42565b6102b4565b60015b60405161ffff9091168152602001610107565b610123610197366004610b42565b6102bf565b6100fd6101aa366004610b42565b6102ca565b602e6100fd565b6101236101c4366004610b42565b6102d5565b6102716101d7366004610b81565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e098891b81166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281518082036052018152607290910190915290565b6040516101079190610c52565b61017661028c366004610b42565b6102e0565b602a6100fd565b60006102a3826102eb565b92915050565b60006102a38261031e565b60006102a38261033f565b60006102a382610360565b60006102a382610381565b60006102a3826103a2565b60006102a3826103c3565b60008161030160015b62ffffff198316906103e4565b5061031562ffffff198416602a6004610508565b91505b50919050565b60008161032b60016102f4565b5061031562ffffff198416602e602061053a565b60008161034c60016102f4565b5061031562ffffff19841660266004610508565b60008161036d60016102f4565b5061031562ffffff198416604e6004610508565b60008161038e60016102f4565b5061031562ffffff1984166006602061053a565b6000816103af60016102f4565b5061031562ffffff19841660026004610508565b6000816103d060016102f4565b5061031562ffffff19841660006002610508565b60006103f0838361072c565b61050157600061040f6104038560d81c90565b64ffffffffff1661074f565b91505060006104248464ffffffffff1661074f565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60405180910390fd5b5090919050565b6000610515826020610c94565b610520906008610cb7565b60ff1661052e85858561053a565b901c90505b9392505050565b60008160ff1660000361054f57506000610533565b6105678460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661058260ff841685610ce0565b1115610614576105e16105a38560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166105c98660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16610839565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60208260ff1611156106a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104f8565b6008820260006106c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b60008164ffffffffff166107408460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156107c257600061076e826008610cb7565b60ff1685901c905061077f816109c9565b61ffff16841793508160ff1660101461079a57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610755565b50600f5b60ff8160ff1610156108335760006107df826008610cb7565b60ff1685901c90506107f0816109c9565b61ffff16831792508160ff1660001461080b57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016107c6565b50915091565b606060006108468661074f565b91505060006108548661074f565b91505060006108628661074f565b91505060006108708661074f565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b60006109db60048360ff16901c6109fb565b60ff1661ffff919091161760081b6109f2826109fb565b60ff1617919050565b600060f08083179060ff82169003610a165750603092915050565b8060ff1660f103610a2a5750603192915050565b8060ff1660f203610a3e5750603292915050565b8060ff1660f303610a525750603392915050565b8060ff1660f403610a665750603492915050565b8060ff1660f503610a7a5750603592915050565b8060ff1660f603610a8e5750603692915050565b8060ff1660f703610aa25750603792915050565b8060ff1660f803610ab65750603892915050565b8060ff1660f903610aca5750603992915050565b8060ff1660fa03610ade5750606192915050565b8060ff1660fb03610af25750606292915050565b8060ff1660fc03610b065750606392915050565b8060ff1660fd03610b1a5750606492915050565b8060ff1660fe03610b2e5750606592915050565b8060ff1660ff036103185750606692915050565b600060208284031215610b5457600080fd5b813562ffffff198116811461053357600080fd5b803563ffffffff81168114610b7c57600080fd5b919050565b60008060008060008060c08789031215610b9a57600080fd5b610ba387610b68565b955060208701359450610bb860408801610b68565b9350610bc660608801610b68565b925060808701359150610bdb60a08801610b68565b90509295509295509295565b6000815180845260005b81811015610c0d57602081850181015186830182015201610bf1565b81811115610c1f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105336020830184610be7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff841680821015610cae57610cae610c65565b90039392505050565b600060ff821660ff84168160ff0481118215151615610cd857610cd8610c65565b029392505050565b60008219821115610cf357610cf3610c65565b50019056fea264697066735822122099b156599b724d59e20ed377892ee914db4ea70fb5a77a6143d26b044e5668fb64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80635cf682c611610097578063a9f877ad11610066578063a9f877ad146101b6578063ac124002146101c9578063ae2ab89f1461027e578063d2c4428a1461029157600080fd5b80635cf682c6146101735780639253ae7714610189578063a0d41e581461019c578063a2ce1f35146101af57600080fd5b80634155c3d5116100d35780634155c3d51461013f578063418fad6d14610146578063569e1eaf1461015957806358c8a98f1461016057600080fd5b806307fd670d146100fa57806311cd4add14610110578063320bfc4414610138575b600080fd5b60065b6040519081526020015b60405180910390f35b61012361011e366004610b42565b610298565b60405163ffffffff9091168152602001610107565b60026100fd565b604e6100fd565b6100fd610154366004610b42565b6102a9565b60266100fd565b61012361016e366004610b42565b6102b4565b60015b60405161ffff9091168152602001610107565b610123610197366004610b42565b6102bf565b6100fd6101aa366004610b42565b6102ca565b602e6100fd565b6101236101c4366004610b42565b6102d5565b6102716101d7366004610b81565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e098891b81166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281518082036052018152607290910190915290565b6040516101079190610c52565b61017661028c366004610b42565b6102e0565b602a6100fd565b60006102a3826102eb565b92915050565b60006102a38261031e565b60006102a38261033f565b60006102a382610360565b60006102a382610381565b60006102a3826103a2565b60006102a3826103c3565b60008161030160015b62ffffff198316906103e4565b5061031562ffffff198416602a6004610508565b91505b50919050565b60008161032b60016102f4565b5061031562ffffff198416602e602061053a565b60008161034c60016102f4565b5061031562ffffff19841660266004610508565b60008161036d60016102f4565b5061031562ffffff198416604e6004610508565b60008161038e60016102f4565b5061031562ffffff1984166006602061053a565b6000816103af60016102f4565b5061031562ffffff19841660026004610508565b6000816103d060016102f4565b5061031562ffffff19841660006002610508565b60006103f0838361072c565b61050157600061040f6104038560d81c90565b64ffffffffff1661074f565b91505060006104248464ffffffffff1661074f565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60405180910390fd5b5090919050565b6000610515826020610c94565b610520906008610cb7565b60ff1661052e85858561053a565b901c90505b9392505050565b60008160ff1660000361054f57506000610533565b6105678460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661058260ff841685610ce0565b1115610614576105e16105a38560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166105c98660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16610839565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60208260ff1611156106a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104f8565b6008820260006106c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b60008164ffffffffff166107408460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156107c257600061076e826008610cb7565b60ff1685901c905061077f816109c9565b61ffff16841793508160ff1660101461079a57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610755565b50600f5b60ff8160ff1610156108335760006107df826008610cb7565b60ff1685901c90506107f0816109c9565b61ffff16831792508160ff1660001461080b57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016107c6565b50915091565b606060006108468661074f565b91505060006108548661074f565b91505060006108628661074f565b91505060006108708661074f565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b60006109db60048360ff16901c6109fb565b60ff1661ffff919091161760081b6109f2826109fb565b60ff1617919050565b600060f08083179060ff82169003610a165750603092915050565b8060ff1660f103610a2a5750603192915050565b8060ff1660f203610a3e5750603292915050565b8060ff1660f303610a525750603392915050565b8060ff1660f403610a665750603492915050565b8060ff1660f503610a7a5750603592915050565b8060ff1660f603610a8e5750603692915050565b8060ff1660f703610aa25750603792915050565b8060ff1660f803610ab65750603892915050565b8060ff1660f903610aca5750603992915050565b8060ff1660fa03610ade5750606192915050565b8060ff1660fb03610af25750606292915050565b8060ff1660fc03610b065750606392915050565b8060ff1660fd03610b1a5750606492915050565b8060ff1660fe03610b2e5750606592915050565b8060ff1660ff036103185750606692915050565b600060208284031215610b5457600080fd5b813562ffffff198116811461053357600080fd5b803563ffffffff81168114610b7c57600080fd5b919050565b60008060008060008060c08789031215610b9a57600080fd5b610ba387610b68565b955060208701359450610bb860408801610b68565b9350610bc660608801610b68565b925060808701359150610bdb60a08801610b68565b90509295509295509295565b6000815180845260005b81811015610c0d57602081850181015186830182015201610bf1565b81811115610c1f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105336020830184610be7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff841680821015610cae57610cae610c65565b90039392505050565b600060ff821660ff84168160ff0481118215151615610cd857610cd8610c65565b029392505050565b60008219821115610cf357610cf3610c65565b50019056fea264697066735822122099b156599b724d59e20ed377892ee914db4ea70fb5a77a6143d26b044e5668fb64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return Header.formatHeader(_originDomain, _sender, _nonce, _destinationDomain, _recipient, _optimisticSeconds);\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"41668:2045:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"41668:2045:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41937:98;34068:1;41937:98;;;160:25:1;;;148:2;133:18;41937:98:0;;;;;;;;43336:118;;;;;;:::i;:::-;;:::i;:::-;;;708:10:1;696:23;;;678:42;;666:2;651:18;43336:118:0;534:192:1;41833:98:0;34019:1;41833:98;;42367:121;34286:2;42367:121;;43460:115;;;;;;:::i;:::-;;:::i;42041:96::-;34116:2;42041:96;;43224:106;;;;;;:::i;:::-;;:::i;41728:99::-;33520:1;41728:99;;;1087:6:1;1075:19;;;1057:38;;1045:2;1030:18;41728:99:0;913:188:1;43581:130:0;;;;;;:::i;:::-;;:::i;43109:109::-;;;;;;:::i;:::-;;:::i;42257:104::-;34224:2;42257:104;;42995:108;;;;;;:::i;:::-;;:::i;42494:366::-;;;;;;:::i;:::-;34671:242;;;3067:16:1;34671:242:0;;;3051:102:1;3172:66;3275:3;3271:16;;;3267:25;;3254:11;;;3247:46;3309:11;;;3302:27;;;;3363:16;;;3359:25;;3345:12;;;3338:47;3419:16;;;3415:25;;3401:12;;;3394:47;3457:12;;;3450:28;;;;3512:16;;;3508:25;;;3494:12;;;3487:47;34671:242:0;;;;;;;;;3550:12:1;;;;34671:242:0;;;;42494:366;;;;;;;;:::i;42866:122::-;;;;;;:::i;:::-;;:::i;42143:108::-;34171:2;42143:108;;43336:118;43395:6;43420:27;43439:7;43420:18;:27::i;:::-;43413:34;43336:118;-1:-1:-1;;43336:118:0:o;43460:115::-;43517:7;43543:25;43560:7;43543:16;:25::i;43224:106::-;43277:6;43302:21;43315:7;43302:12;:21::i;43581:130::-;43646:6;43671:33;43696:7;43671:24;:33::i;43109:109::-;43163:7;43189:22;43203:7;43189:13;:22::i;42995:108::-;43049:6;43074:22;43088:7;43074:13;:22::i;42866:122::-;42927:6;42952:29;42973:7;42952:20;:29::i;35861:161::-;35942:6;35924:7;34340:37;37330:12;37323:20;-1:-1:-1;;34340:16:0;;;;:37::i;:::-;-1:-1:-1;35974:40:0::1;-1:-1:-1::0;;35974:17:0;::::1;34171:2;36012:1;35974:17;:40::i;:::-;35960:55;;34387:1;35861:161:::0;;;;:::o;36088:147::-;36167:7;36149;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;36193:35:0::1;-1:-1:-1::0;;36193:13:0;::::1;34224:2;36225;36193:13;:35::i;35655:149::-:0;35730:6;35712:7;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;35762:34:0::1;-1:-1:-1::0;;35762:17:0;::::1;34116:2;35794:1;35762:17;:34::i;36299:174::-:0;36386:6;36368:7;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;36418:47:0::1;-1:-1:-1::0;;36418:17:0;::::1;34286:2;36463:1;36418:17;:47::i;35463:141::-:0;35539:7;35521;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;35565:32:0::1;-1:-1:-1::0;;35565:13:0;::::1;34068:1;35594:2;35565:13;:32::i;35260:151::-:0;35336:6;35318:7;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;35368:35:0::1;-1:-1:-1::0;;35368:17:0;::::1;34019:1;35401;35368:17;:35::i;35062:146::-:0;35145:6;35127:7;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;35177:23:0::1;-1:-1:-1::0;;35177:17:0;::::1;35195:1;35198;35177:17;:23::i;10073:578::-:0;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;3940:31:1;10385:186:0;;;3928:44:1;3991:66;4095:3;4091:16;;;4087:25;;4073:12;;;4066:47;4143:15;4129:12;;;4122:37;4193:16;;;4189:25;4175:12;;;4168:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;4231:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;;;;;;;;;;:::i;:::-;;;;;;;;10170:451;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;-1:-1:-1;21121:221:0;;;;;;:::o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;;;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;;;;5445:2:1;20359:83:0;;;5427:21:1;5484:2;5464:18;;;5457:30;5523:34;5503:18;;;5496:62;5594:28;5574:18;;;5567:56;5640:19;;20359:83:0;5243:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19130:355;;;6511:34:1;19130:355:0;;;6499:47:1;6576:23;6562:12;;;6555:45;6619:66;6723:3;6719:16;;;6715:25;;6701:12;;;6694:47;6760:17;6793:12;;;6786:24;;;6844:16;;;6840:25;;6826:12;;;6819:47;6896:34;6882:12;;;6875:56;6962:3;6947:13;;;6940:26;7001:16;;;6997:25;;6982:13;;;6975:48;7039:13;;;7032:25;;;;7092:16;;7088:25;;;7073:13;;;7066:48;-1:-1:-1;;5747:3:1;7160:13;;;5735:16;19130:355:0;;;;;;;;;5767:11:1;;;;19130:355:0;;;;;-1:-1:-1;;;;;18761:741:0:o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;2943:1393::-;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;196:333:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;363:9;350:23;-1:-1:-1;;406:5:1;402:78;395:5;392:89;382:117;;495:1;492;485:12;1106:163;1173:20;;1233:10;1222:22;;1212:33;;1202:61;;1259:1;1256;1249:12;1202:61;1106:163;;;:::o;1274:539::-;1374:6;1382;1390;1398;1406;1414;1467:3;1455:9;1446:7;1442:23;1438:33;1435:53;;;1484:1;1481;1474:12;1435:53;1507:28;1525:9;1507:28;:::i;:::-;1497:38;;1582:2;1571:9;1567:18;1554:32;1544:42;;1605:37;1638:2;1627:9;1623:18;1605:37;:::i;:::-;1595:47;;1661:37;1694:2;1683:9;1679:18;1661:37;:::i;:::-;1651:47;;1745:3;1734:9;1730:19;1717:33;1707:43;;1769:38;1802:3;1791:9;1787:19;1769:38;:::i;:::-;1759:48;;1274:539;;;;;;;;:::o;1818:530::-;1859:3;1897:5;1891:12;1924:6;1919:3;1912:19;1949:1;1959:162;1973:6;1970:1;1967:13;1959:162;;;2035:4;2091:13;;;2087:22;;2081:29;2063:11;;;2059:20;;2052:59;1988:12;1959:162;;;2139:6;2136:1;2133:13;2130:87;;;2205:1;2198:4;2189:6;2184:3;2180:16;2176:27;2169:38;2130:87;-1:-1:-1;2262:2:1;2250:15;2267:66;2246:88;2237:98;;;;2337:4;2233:109;;1818:530;-1:-1:-1;;1818:530:1:o;2353:217::-;2500:2;2489:9;2482:21;2463:4;2520:44;2560:2;2549:9;2545:18;2537:6;2520:44;:::i;4478:184::-;4530:77;4527:1;4520:88;4627:4;4624:1;4617:15;4651:4;4648:1;4641:15;4667:195;4705:4;4742;4739:1;4735:12;4774:4;4771:1;4767:12;4799:3;4794;4791:12;4788:38;;;4806:18;;:::i;:::-;4843:13;;;4667:195;-1:-1:-1;;;4667:195:1:o;4867:238::-;4905:7;4945:4;4942:1;4938:12;4977:4;4974:1;4970:12;5037:3;5031:4;5027:14;5022:3;5019:23;5012:3;5005:11;4998:19;4994:49;4991:75;;;5046:18;;:::i;:::-;5086:13;;4867:238;-1:-1:-1;;;4867:238:1:o;5110:128::-;5150:3;5181:1;5177:6;5174:1;5171:13;5168:39;;;5187:18;;:::i;:::-;-1:-1:-1;5223:9:1;;5110:128::o","abiDefinition":[{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"destination","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_originDomain","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"}],"name":"formatHeader","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"headerVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"headerVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetDestination","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetOptimisticSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetOrigin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetRecipient","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetSender","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"optimisticSeconds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"origin","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"recipient","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"sender","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"destination\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_originDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipient\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"}],\"name\":\"formatHeader\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"headerVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"headerVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetDestination\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetOptimisticSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetOrigin\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetRecipient\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetSender\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"optimisticSeconds\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"origin\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"recipient\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"sender\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"HeaderHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x2cb76221c7acc178581b6d31566d309b1db38b4ef6e9037272d9b623d86315eb\",\"urls\":[\"bzz-raw://6d493a81dd7f7e24669dd157df510333ed97c4a00632a634d8232cafdcbb6199\",\"dweb:/ipfs/QmYYog547KTpsFFiP5RwfbL8hQ7SS3kPYpbFXf4RdmwpQc\"]}},\"version\":1}"},"hashes":{"destination(bytes29)":"11cd4add","formatHeader(uint32,bytes32,uint32,uint32,bytes32,uint32)":"ac124002","headerVersion()":"5cf682c6","headerVersion(bytes29)":"ae2ab89f","nonce(bytes29)":"58c8a98f","offsetDestination()":"d2c4428a","offsetNonce()":"569e1eaf","offsetOptimisticSeconds()":"4155c3d5","offsetOrigin()":"320bfc44","offsetRecipient()":"a2ce1f35","offsetSender()":"07fd670d","optimisticSeconds(bytes29)":"9253ae77","origin(bytes29)":"a9f877ad","recipient(bytes29)":"418fad6d","sender(bytes29)":"a0d41e58"}},"solidity/HeaderHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b6c73bc0d6ab1fe8ea56cb2e3eefe470c06b44d4d68cc277c37ce9676ce6e0f664736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b6c73bc0d6ab1fe8ea56cb2e3eefe470c06b44d4d68cc277c37ce9676ce6e0f664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return Header.formatHeader(_originDomain, _sender, _nonce, _destinationDomain, _recipient, _optimisticSeconds);\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"36691:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;36691:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"36691:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x2cb76221c7acc178581b6d31566d309b1db38b4ef6e9037272d9b623d86315eb\",\"urls\":[\"bzz-raw://6d493a81dd7f7e24669dd157df510333ed97c4a00632a634d8232cafdcbb6199\",\"dweb:/ipfs/QmYYog547KTpsFFiP5RwfbL8hQ7SS3kPYpbFXf4RdmwpQc\"]}},\"version\":1}"},"hashes":{}},"solidity/HeaderHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220da8acce1cdc21bb132761fab03293e69f28573630e8aab824a3b6aee2410d47164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220da8acce1cdc21bb132761fab03293e69f28573630e8aab824a3b6aee2410d47164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return Header.formatHeader(_originDomain, _sender, _nonce, _destinationDomain, _recipient, _optimisticSeconds);\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32274:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32274:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32274:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x2cb76221c7acc178581b6d31566d309b1db38b4ef6e9037272d9b623d86315eb\",\"urls\":[\"bzz-raw://6d493a81dd7f7e24669dd157df510333ed97c4a00632a634d8232cafdcbb6199\",\"dweb:/ipfs/QmYYog547KTpsFFiP5RwfbL8hQ7SS3kPYpbFXf4RdmwpQc\"]}},\"version\":1}"},"hashes":{}},"solidity/HeaderHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122085ba6896a6f6b5ccc9a976dcfdb6a3e58a759dcaaad8fd8a23d7b5ab4f5f937664736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122085ba6896a6f6b5ccc9a976dcfdb6a3e58a759dcaaad8fd8a23d7b5ab4f5f937664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return Header.formatHeader(_originDomain, _sender, _nonce, _destinationDomain, _recipient, _optimisticSeconds);\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x2cb76221c7acc178581b6d31566d309b1db38b4ef6e9037272d9b623d86315eb\",\"urls\":[\"bzz-raw://6d493a81dd7f7e24669dd157df510333ed97c4a00632a634d8232cafdcbb6199\",\"dweb:/ipfs/QmYYog547KTpsFFiP5RwfbL8hQ7SS3kPYpbFXf4RdmwpQc\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}}} \ No newline at end of file +{"solidity/HeaderHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220340f846ad6fee7367710f26f24839fc8304fff32c7eb1785147ddb38a4901dae64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220340f846ad6fee7367710f26f24839fc8304fff32c7eb1785147ddb38a4901dae64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return\n Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33386:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33386:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33386:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x8cb2cfe9f09b908a0e1e1b8835cfbf4bad0a79fd78c7f67926824206dc2d8b67\",\"urls\":[\"bzz-raw://ea2ce5d34aaa276abb659569f461e76f291073b97adcad2c567ee9c46e94e2b6\",\"dweb:/ipfs/QmXwn5u1FnPHEEpGvkPEYjr4JjN2LgkmrA7xhgLb11JPym\"]}},\"version\":1}"},"hashes":{}},"solidity/HeaderHarness.sol:HeaderHarness":{"code":"0x608060405234801561001057600080fd5b50610d2e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80635cf682c611610097578063a9f877ad11610066578063a9f877ad146101b6578063ac124002146101c9578063ae2ab89f1461027e578063d2c4428a1461029157600080fd5b80635cf682c6146101735780639253ae7714610189578063a0d41e581461019c578063a2ce1f35146101af57600080fd5b80634155c3d5116100d35780634155c3d51461013f578063418fad6d14610146578063569e1eaf1461015957806358c8a98f1461016057600080fd5b806307fd670d146100fa57806311cd4add14610110578063320bfc4414610138575b600080fd5b60065b6040519081526020015b60405180910390f35b61012361011e366004610b42565b610298565b60405163ffffffff9091168152602001610107565b60026100fd565b604e6100fd565b6100fd610154366004610b42565b6102a9565b60266100fd565b61012361016e366004610b42565b6102b4565b60015b60405161ffff9091168152602001610107565b610123610197366004610b42565b6102bf565b6100fd6101aa366004610b42565b6102ca565b602e6100fd565b6101236101c4366004610b42565b6102d5565b6102716101d7366004610b81565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e098891b81166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281518082036052018152607290910190915290565b6040516101079190610c52565b61017661028c366004610b42565b6102e0565b602a6100fd565b60006102a3826102eb565b92915050565b60006102a38261031e565b60006102a38261033f565b60006102a382610360565b60006102a382610381565b60006102a3826103a2565b60006102a3826103c3565b60008161030160015b62ffffff198316906103e4565b5061031562ffffff198416602a6004610508565b91505b50919050565b60008161032b60016102f4565b5061031562ffffff198416602e602061053a565b60008161034c60016102f4565b5061031562ffffff19841660266004610508565b60008161036d60016102f4565b5061031562ffffff198416604e6004610508565b60008161038e60016102f4565b5061031562ffffff1984166006602061053a565b6000816103af60016102f4565b5061031562ffffff19841660026004610508565b6000816103d060016102f4565b5061031562ffffff19841660006002610508565b60006103f0838361072c565b61050157600061040f6104038560d81c90565b64ffffffffff1661074f565b91505060006104248464ffffffffff1661074f565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60405180910390fd5b5090919050565b6000610515826020610c94565b610520906008610cb7565b60ff1661052e85858561053a565b901c90505b9392505050565b60008160ff1660000361054f57506000610533565b6105678460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661058260ff841685610ce0565b1115610614576105e16105a38560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166105c98660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16610839565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60208260ff1611156106a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104f8565b6008820260006106c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b60008164ffffffffff166107408460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156107c257600061076e826008610cb7565b60ff1685901c905061077f816109c9565b61ffff16841793508160ff1660101461079a57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610755565b50600f5b60ff8160ff1610156108335760006107df826008610cb7565b60ff1685901c90506107f0816109c9565b61ffff16831792508160ff1660001461080b57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016107c6565b50915091565b606060006108468661074f565b91505060006108548661074f565b91505060006108628661074f565b91505060006108708661074f565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b60006109db60048360ff16901c6109fb565b60ff1661ffff919091161760081b6109f2826109fb565b60ff1617919050565b600060f08083179060ff82169003610a165750603092915050565b8060ff1660f103610a2a5750603192915050565b8060ff1660f203610a3e5750603292915050565b8060ff1660f303610a525750603392915050565b8060ff1660f403610a665750603492915050565b8060ff1660f503610a7a5750603592915050565b8060ff1660f603610a8e5750603692915050565b8060ff1660f703610aa25750603792915050565b8060ff1660f803610ab65750603892915050565b8060ff1660f903610aca5750603992915050565b8060ff1660fa03610ade5750606192915050565b8060ff1660fb03610af25750606292915050565b8060ff1660fc03610b065750606392915050565b8060ff1660fd03610b1a5750606492915050565b8060ff1660fe03610b2e5750606592915050565b8060ff1660ff036103185750606692915050565b600060208284031215610b5457600080fd5b813562ffffff198116811461053357600080fd5b803563ffffffff81168114610b7c57600080fd5b919050565b60008060008060008060c08789031215610b9a57600080fd5b610ba387610b68565b955060208701359450610bb860408801610b68565b9350610bc660608801610b68565b925060808701359150610bdb60a08801610b68565b90509295509295509295565b6000815180845260005b81811015610c0d57602081850181015186830182015201610bf1565b81811115610c1f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105336020830184610be7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff841680821015610cae57610cae610c65565b90039392505050565b600060ff821660ff84168160ff0481118215151615610cd857610cd8610c65565b029392505050565b60008219821115610cf357610cf3610c65565b50019056fea2646970667358221220a46e5ae0ecbe858653f5c1f2078791ef504340f562b34d0c41021648aaab650764736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80635cf682c611610097578063a9f877ad11610066578063a9f877ad146101b6578063ac124002146101c9578063ae2ab89f1461027e578063d2c4428a1461029157600080fd5b80635cf682c6146101735780639253ae7714610189578063a0d41e581461019c578063a2ce1f35146101af57600080fd5b80634155c3d5116100d35780634155c3d51461013f578063418fad6d14610146578063569e1eaf1461015957806358c8a98f1461016057600080fd5b806307fd670d146100fa57806311cd4add14610110578063320bfc4414610138575b600080fd5b60065b6040519081526020015b60405180910390f35b61012361011e366004610b42565b610298565b60405163ffffffff9091168152602001610107565b60026100fd565b604e6100fd565b6100fd610154366004610b42565b6102a9565b60266100fd565b61012361016e366004610b42565b6102b4565b60015b60405161ffff9091168152602001610107565b610123610197366004610b42565b6102bf565b6100fd6101aa366004610b42565b6102ca565b602e6100fd565b6101236101c4366004610b42565b6102d5565b6102716101d7366004610b81565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e098891b81166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281518082036052018152607290910190915290565b6040516101079190610c52565b61017661028c366004610b42565b6102e0565b602a6100fd565b60006102a3826102eb565b92915050565b60006102a38261031e565b60006102a38261033f565b60006102a382610360565b60006102a382610381565b60006102a3826103a2565b60006102a3826103c3565b60008161030160015b62ffffff198316906103e4565b5061031562ffffff198416602a6004610508565b91505b50919050565b60008161032b60016102f4565b5061031562ffffff198416602e602061053a565b60008161034c60016102f4565b5061031562ffffff19841660266004610508565b60008161036d60016102f4565b5061031562ffffff198416604e6004610508565b60008161038e60016102f4565b5061031562ffffff1984166006602061053a565b6000816103af60016102f4565b5061031562ffffff19841660026004610508565b6000816103d060016102f4565b5061031562ffffff19841660006002610508565b60006103f0838361072c565b61050157600061040f6104038560d81c90565b64ffffffffff1661074f565b91505060006104248464ffffffffff1661074f565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60405180910390fd5b5090919050565b6000610515826020610c94565b610520906008610cb7565b60ff1661052e85858561053a565b901c90505b9392505050565b60008160ff1660000361054f57506000610533565b6105678460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661058260ff841685610ce0565b1115610614576105e16105a38560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166105c98660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16610839565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f89190610c52565b60208260ff1611156106a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104f8565b6008820260006106c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b60008164ffffffffff166107408460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156107c257600061076e826008610cb7565b60ff1685901c905061077f816109c9565b61ffff16841793508160ff1660101461079a57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610755565b50600f5b60ff8160ff1610156108335760006107df826008610cb7565b60ff1685901c90506107f0816109c9565b61ffff16831792508160ff1660001461080b57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016107c6565b50915091565b606060006108468661074f565b91505060006108548661074f565b91505060006108628661074f565b91505060006108708661074f565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b60006109db60048360ff16901c6109fb565b60ff1661ffff919091161760081b6109f2826109fb565b60ff1617919050565b600060f08083179060ff82169003610a165750603092915050565b8060ff1660f103610a2a5750603192915050565b8060ff1660f203610a3e5750603292915050565b8060ff1660f303610a525750603392915050565b8060ff1660f403610a665750603492915050565b8060ff1660f503610a7a5750603592915050565b8060ff1660f603610a8e5750603692915050565b8060ff1660f703610aa25750603792915050565b8060ff1660f803610ab65750603892915050565b8060ff1660f903610aca5750603992915050565b8060ff1660fa03610ade5750606192915050565b8060ff1660fb03610af25750606292915050565b8060ff1660fc03610b065750606392915050565b8060ff1660fd03610b1a5750606492915050565b8060ff1660fe03610b2e5750606592915050565b8060ff1660ff036103185750606692915050565b600060208284031215610b5457600080fd5b813562ffffff198116811461053357600080fd5b803563ffffffff81168114610b7c57600080fd5b919050565b60008060008060008060c08789031215610b9a57600080fd5b610ba387610b68565b955060208701359450610bb860408801610b68565b9350610bc660608801610b68565b925060808701359150610bdb60a08801610b68565b90509295509295509295565b6000815180845260005b81811015610c0d57602081850181015186830182015201610bf1565b81811115610c1f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105336020830184610be7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff841680821015610cae57610cae610c65565b90039392505050565b600060ff821660ff84168160ff0481118215151615610cd857610cd8610c65565b029392505050565b60008219821115610cf357610cf3610c65565b50019056fea2646970667358221220a46e5ae0ecbe858653f5c1f2078791ef504340f562b34d0c41021648aaab650764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return\n Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"41668:2166:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"41668:2166:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41937:98;34068:1;41937:98;;;160:25:1;;;148:2;133:18;41937:98:0;;;;;;;;43457:118;;;;;;:::i;:::-;;:::i;:::-;;;708:10:1;696:23;;;678:42;;666:2;651:18;43457:118:0;534:192:1;41833:98:0;34019:1;41833:98;;42367:121;34286:2;42367:121;;43581:115;;;;;;:::i;:::-;;:::i;42041:96::-;34116:2;42041:96;;43345:106;;;;;;:::i;:::-;;:::i;41728:99::-;33520:1;41728:99;;;1087:6:1;1075:19;;;1057:38;;1045:2;1030:18;41728:99:0;913:188:1;43702:130:0;;;;;;:::i;:::-;;:::i;43230:109::-;;;;;;:::i;:::-;;:::i;42257:104::-;34224:2;42257:104;;43116:108;;;;;;:::i;:::-;;:::i;42494:488::-;;;;;;:::i;:::-;34671:242;;;3067:16:1;34671:242:0;;;3051:102:1;3172:66;3275:3;3271:16;;;3267:25;;3254:11;;;3247:46;3309:11;;;3302:27;;;;3363:16;;;3359:25;;3345:12;;;3338:47;3419:16;;;3415:25;;3401:12;;;3394:47;3457:12;;;3450:28;;;;3512:16;;;3508:25;;;3494:12;;;3487:47;34671:242:0;;;;;;;;;3550:12:1;;;;34671:242:0;;;;42494:488;;;;;;;;:::i;42988:122::-;;;;;;:::i;:::-;;:::i;42143:108::-;34171:2;42143:108;;43457:118;43516:6;43541:27;43560:7;43541:18;:27::i;:::-;43534:34;43457:118;-1:-1:-1;;43457:118:0:o;43581:115::-;43638:7;43664:25;43681:7;43664:16;:25::i;43345:106::-;43398:6;43423:21;43436:7;43423:12;:21::i;43702:130::-;43767:6;43792:33;43817:7;43792:24;:33::i;43230:109::-;43284:7;43310:22;43324:7;43310:13;:22::i;43116:108::-;43170:6;43195:22;43209:7;43195:13;:22::i;42988:122::-;43049:6;43074:29;43095:7;43074:20;:29::i;35861:161::-;35942:6;35924:7;34340:37;37330:12;37323:20;-1:-1:-1;;34340:16:0;;;;:37::i;:::-;-1:-1:-1;35974:40:0::1;-1:-1:-1::0;;35974:17:0;::::1;34171:2;36012:1;35974:17;:40::i;:::-;35960:55;;34387:1;35861:161:::0;;;;:::o;36088:147::-;36167:7;36149;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;36193:35:0::1;-1:-1:-1::0;;36193:13:0;::::1;34224:2;36225;36193:13;:35::i;35655:149::-:0;35730:6;35712:7;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;35762:34:0::1;-1:-1:-1::0;;35762:17:0;::::1;34116:2;35794:1;35762:17;:34::i;36299:174::-:0;36386:6;36368:7;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;36418:47:0::1;-1:-1:-1::0;;36418:17:0;::::1;34286:2;36463:1;36418:17;:47::i;35463:141::-:0;35539:7;35521;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;35565:32:0::1;-1:-1:-1::0;;35565:13:0;::::1;34068:1;35594:2;35565:13;:32::i;35260:151::-:0;35336:6;35318:7;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;35368:35:0::1;-1:-1:-1::0;;35368:17:0;::::1;34019:1;35401;35368:17;:35::i;35062:146::-:0;35145:6;35127:7;34340:37;37330:12;37323:20;;34340:37;-1:-1:-1;35177:23:0::1;-1:-1:-1::0;;35177:17:0;::::1;35195:1;35198;35177:17;:23::i;10073:578::-:0;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;3940:31:1;10385:186:0;;;3928:44:1;3991:66;4095:3;4091:16;;;4087:25;;4073:12;;;4066:47;4143:15;4129:12;;;4122:37;4193:16;;;4189:25;4175:12;;;4168:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;4231:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;;;;;;;;;;:::i;:::-;;;;;;;;10170:451;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;-1:-1:-1;21121:221:0;;;;;;:::o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;;;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;;;;5445:2:1;20359:83:0;;;5427:21:1;5484:2;5464:18;;;5457:30;5523:34;5503:18;;;5496:62;5594:28;5574:18;;;5567:56;5640:19;;20359:83:0;5243:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19130:355;;;6511:34:1;19130:355:0;;;6499:47:1;6576:23;6562:12;;;6555:45;6619:66;6723:3;6719:16;;;6715:25;;6701:12;;;6694:47;6760:17;6793:12;;;6786:24;;;6844:16;;;6840:25;;6826:12;;;6819:47;6896:34;6882:12;;;6875:56;6962:3;6947:13;;;6940:26;7001:16;;;6997:25;;6982:13;;;6975:48;7039:13;;;7032:25;;;;7092:16;;7088:25;;;7073:13;;;7066:48;-1:-1:-1;;5747:3:1;7160:13;;;5735:16;19130:355:0;;;;;;;;;5767:11:1;;;;19130:355:0;;;;;-1:-1:-1;;;;;18761:741:0:o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;2943:1393::-;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;196:333:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;363:9;350:23;-1:-1:-1;;406:5:1;402:78;395:5;392:89;382:117;;495:1;492;485:12;1106:163;1173:20;;1233:10;1222:22;;1212:33;;1202:61;;1259:1;1256;1249:12;1202:61;1106:163;;;:::o;1274:539::-;1374:6;1382;1390;1398;1406;1414;1467:3;1455:9;1446:7;1442:23;1438:33;1435:53;;;1484:1;1481;1474:12;1435:53;1507:28;1525:9;1507:28;:::i;:::-;1497:38;;1582:2;1571:9;1567:18;1554:32;1544:42;;1605:37;1638:2;1627:9;1623:18;1605:37;:::i;:::-;1595:47;;1661:37;1694:2;1683:9;1679:18;1661:37;:::i;:::-;1651:47;;1745:3;1734:9;1730:19;1717:33;1707:43;;1769:38;1802:3;1791:9;1787:19;1769:38;:::i;:::-;1759:48;;1274:539;;;;;;;;:::o;1818:530::-;1859:3;1897:5;1891:12;1924:6;1919:3;1912:19;1949:1;1959:162;1973:6;1970:1;1967:13;1959:162;;;2035:4;2091:13;;;2087:22;;2081:29;2063:11;;;2059:20;;2052:59;1988:12;1959:162;;;2139:6;2136:1;2133:13;2130:87;;;2205:1;2198:4;2189:6;2184:3;2180:16;2176:27;2169:38;2130:87;-1:-1:-1;2262:2:1;2250:15;2267:66;2246:88;2237:98;;;;2337:4;2233:109;;1818:530;-1:-1:-1;;1818:530:1:o;2353:217::-;2500:2;2489:9;2482:21;2463:4;2520:44;2560:2;2549:9;2545:18;2537:6;2520:44;:::i;4478:184::-;4530:77;4527:1;4520:88;4627:4;4624:1;4617:15;4651:4;4648:1;4641:15;4667:195;4705:4;4742;4739:1;4735:12;4774:4;4771:1;4767:12;4799:3;4794;4791:12;4788:38;;;4806:18;;:::i;:::-;4843:13;;;4667:195;-1:-1:-1;;;4667:195:1:o;4867:238::-;4905:7;4945:4;4942:1;4938:12;4977:4;4974:1;4970:12;5037:3;5031:4;5027:14;5022:3;5019:23;5012:3;5005:11;4998:19;4994:49;4991:75;;;5046:18;;:::i;:::-;5086:13;;4867:238;-1:-1:-1;;;4867:238:1:o;5110:128::-;5150:3;5181:1;5177:6;5174:1;5171:13;5168:39;;;5187:18;;:::i;:::-;-1:-1:-1;5223:9:1;;5110:128::o","abiDefinition":[{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"destination","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_originDomain","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"}],"name":"formatHeader","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"headerVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"headerVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetDestination","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetOptimisticSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetOrigin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetRecipient","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetSender","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"optimisticSeconds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"origin","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"recipient","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_header","type":"bytes29"}],"name":"sender","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"destination\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_originDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipient\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"}],\"name\":\"formatHeader\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"headerVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"headerVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetDestination\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetOptimisticSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetOrigin\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetRecipient\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetSender\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"optimisticSeconds\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"origin\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"recipient\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_header\",\"type\":\"bytes29\"}],\"name\":\"sender\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"HeaderHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x8cb2cfe9f09b908a0e1e1b8835cfbf4bad0a79fd78c7f67926824206dc2d8b67\",\"urls\":[\"bzz-raw://ea2ce5d34aaa276abb659569f461e76f291073b97adcad2c567ee9c46e94e2b6\",\"dweb:/ipfs/QmXwn5u1FnPHEEpGvkPEYjr4JjN2LgkmrA7xhgLb11JPym\"]}},\"version\":1}"},"hashes":{"destination(bytes29)":"11cd4add","formatHeader(uint32,bytes32,uint32,uint32,bytes32,uint32)":"ac124002","headerVersion()":"5cf682c6","headerVersion(bytes29)":"ae2ab89f","nonce(bytes29)":"58c8a98f","offsetDestination()":"d2c4428a","offsetNonce()":"569e1eaf","offsetOptimisticSeconds()":"4155c3d5","offsetOrigin()":"320bfc44","offsetRecipient()":"a2ce1f35","offsetSender()":"07fd670d","optimisticSeconds(bytes29)":"9253ae77","origin(bytes29)":"a9f877ad","recipient(bytes29)":"418fad6d","sender(bytes29)":"a0d41e58"}},"solidity/HeaderHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205de236cc79dd1a35910b8896839cd6cea3071d602ed924e656ddb553d444554c64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205de236cc79dd1a35910b8896839cd6cea3071d602ed924e656ddb553d444554c64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return\n Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"36691:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;36691:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"36691:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x8cb2cfe9f09b908a0e1e1b8835cfbf4bad0a79fd78c7f67926824206dc2d8b67\",\"urls\":[\"bzz-raw://ea2ce5d34aaa276abb659569f461e76f291073b97adcad2c567ee9c46e94e2b6\",\"dweb:/ipfs/QmXwn5u1FnPHEEpGvkPEYjr4JjN2LgkmrA7xhgLb11JPym\"]}},\"version\":1}"},"hashes":{}},"solidity/HeaderHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220be30b0ec5d51a8266770aec2af16b2b406e1b86ecb83c8ec4f55b83b1c563db164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220be30b0ec5d51a8266770aec2af16b2b406e1b86ecb83c8ec4f55b83b1c563db164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return\n Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32274:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32274:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32274:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x8cb2cfe9f09b908a0e1e1b8835cfbf4bad0a79fd78c7f67926824206dc2d8b67\",\"urls\":[\"bzz-raw://ea2ce5d34aaa276abb659569f461e76f291073b97adcad2c567ee9c46e94e2b6\",\"dweb:/ipfs/QmXwn5u1FnPHEEpGvkPEYjr4JjN2LgkmrA7xhgLb11JPym\"]}},\"version\":1}"},"hashes":{}},"solidity/HeaderHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220638f5e4bebb379c68231cb1f255621661becf1becd3d8c455549ffc24d5f3ab264736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220638f5e4bebb379c68231cb1f255621661becf1becd3d8c455549ffc24d5f3ab264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\n// \ncontract HeaderHarness {\n using Header for bytes29;\n\n function headerVersion() public pure returns (uint16) {\n return Header.HEADER_VERSION;\n }\n\n function offsetOrigin() public pure returns (uint256) {\n return Header.OFFSET_ORIGIN;\n }\n\n function offsetSender() public pure returns (uint256) {\n return Header.OFFSET_SENDER;\n }\n\n function offsetNonce() public pure returns (uint256) {\n return Header.OFFSET_NONCE;\n }\n\n function offsetDestination() public pure returns (uint256) {\n return Header.OFFSET_DESTINATION;\n }\n\n function offsetRecipient() public pure returns (uint256) {\n return Header.OFFSET_RECIPIENT;\n }\n\n function offsetOptimisticSeconds() public pure returns (uint256) {\n return Header.OFFSET_OPTIMISTIC_SECONDS;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) public pure returns (bytes memory) {\n return\n Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerVersion(bytes29 _header) public pure returns (uint16) {\n return Header.headerVersion(_header);\n }\n\n function origin(bytes29 _header) public pure returns (uint32) {\n return Header.origin(_header);\n }\n\n function sender(bytes29 _header) public pure returns (bytes32) {\n return Header.sender(_header);\n }\n\n function nonce(bytes29 _header) public pure returns (uint32) {\n return Header.nonce(_header);\n }\n\n function destination(bytes29 _header) public pure returns (uint32) {\n return Header.destination(_header);\n }\n\n function recipient(bytes29 _header) public pure returns (bytes32) {\n return Header.recipient(_header);\n }\n\n function optimisticSeconds(bytes29 _header) public pure returns (uint32) {\n return Header.optimisticSeconds(_header);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HeaderHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HeaderHarness.sol\":{\"keccak256\":\"0x8cb2cfe9f09b908a0e1e1b8835cfbf4bad0a79fd78c7f67926824206dc2d8b67\",\"urls\":[\"bzz-raw://ea2ce5d34aaa276abb659569f461e76f291073b97adcad2c567ee9c46e94e2b6\",\"dweb:/ipfs/QmXwn5u1FnPHEEpGvkPEYjr4JjN2LgkmrA7xhgLb11JPym\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}}} \ No newline at end of file diff --git a/core/contracts/test/homeharness/homeharness.abigen.go b/core/contracts/test/homeharness/homeharness.abigen.go index bd39f57971..0126143d17 100644 --- a/core/contracts/test/homeharness/homeharness.abigen.go +++ b/core/contracts/test/homeharness/homeharness.abigen.go @@ -28,10 +28,312 @@ var ( _ = event.NewSubscription ) +// AbstractGuardRegistryMetaData contains all meta data concerning the AbstractGuardRegistry contract. +var AbstractGuardRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractGuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractGuardRegistryMetaData.ABI instead. +var AbstractGuardRegistryABI = AbstractGuardRegistryMetaData.ABI + +// AbstractGuardRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractGuardRegistry struct { + AbstractGuardRegistryCaller // Read-only binding to the contract + AbstractGuardRegistryTransactor // Write-only binding to the contract + AbstractGuardRegistryFilterer // Log filterer for contract events +} + +// AbstractGuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractGuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractGuardRegistrySession struct { + Contract *AbstractGuardRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractGuardRegistryCallerSession struct { + Contract *AbstractGuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractGuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractGuardRegistryTransactorSession struct { + Contract *AbstractGuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractGuardRegistryRaw struct { + Contract *AbstractGuardRegistry // Generic contract binding to access the raw methods on +} + +// AbstractGuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCallerRaw struct { + Contract *AbstractGuardRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractGuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactorRaw struct { + Contract *AbstractGuardRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractGuardRegistry creates a new instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistry(address common.Address, backend bind.ContractBackend) (*AbstractGuardRegistry, error) { + contract, err := bindAbstractGuardRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractGuardRegistry{AbstractGuardRegistryCaller: AbstractGuardRegistryCaller{contract: contract}, AbstractGuardRegistryTransactor: AbstractGuardRegistryTransactor{contract: contract}, AbstractGuardRegistryFilterer: AbstractGuardRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractGuardRegistryCaller creates a new read-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractGuardRegistryCaller, error) { + contract, err := bindAbstractGuardRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryCaller{contract: contract}, nil +} + +// NewAbstractGuardRegistryTransactor creates a new write-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractGuardRegistryTransactor, error) { + contract, err := bindAbstractGuardRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryTransactor{contract: contract}, nil +} + +// NewAbstractGuardRegistryFilterer creates a new log filterer instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractGuardRegistryFilterer, error) { + contract, err := bindAbstractGuardRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryFilterer{contract: contract}, nil +} + +// bindAbstractGuardRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractGuardRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transact(opts, method, params...) +} + +// AbstractNotaryRegistryMetaData contains all meta data concerning the AbstractNotaryRegistry contract. +var AbstractNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractNotaryRegistryMetaData.ABI instead. +var AbstractNotaryRegistryABI = AbstractNotaryRegistryMetaData.ABI + +// AbstractNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractNotaryRegistry struct { + AbstractNotaryRegistryCaller // Read-only binding to the contract + AbstractNotaryRegistryTransactor // Write-only binding to the contract + AbstractNotaryRegistryFilterer // Log filterer for contract events +} + +// AbstractNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractNotaryRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractNotaryRegistrySession struct { + Contract *AbstractNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractNotaryRegistryCallerSession struct { + Contract *AbstractNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractNotaryRegistryTransactorSession struct { + Contract *AbstractNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractNotaryRegistryRaw struct { + Contract *AbstractNotaryRegistry // Generic contract binding to access the raw methods on +} + +// AbstractNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCallerRaw struct { + Contract *AbstractNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactorRaw struct { + Contract *AbstractNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractNotaryRegistry creates a new instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistry(address common.Address, backend bind.ContractBackend) (*AbstractNotaryRegistry, error) { + contract, err := bindAbstractNotaryRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistry{AbstractNotaryRegistryCaller: AbstractNotaryRegistryCaller{contract: contract}, AbstractNotaryRegistryTransactor: AbstractNotaryRegistryTransactor{contract: contract}, AbstractNotaryRegistryFilterer: AbstractNotaryRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractNotaryRegistryCaller creates a new read-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractNotaryRegistryCaller, error) { + contract, err := bindAbstractNotaryRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryCaller{contract: contract}, nil +} + +// NewAbstractNotaryRegistryTransactor creates a new write-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractNotaryRegistryTransactor, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryTransactor{contract: contract}, nil +} + +// NewAbstractNotaryRegistryFilterer creates a new log filterer instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractNotaryRegistryFilterer, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryFilterer{contract: contract}, nil +} + +// bindAbstractNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractNotaryRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transact(opts, method, params...) +} + // AddressMetaData contains all meta data concerning the Address contract. var AddressMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e0cc99aae109d4df65d4cbc28dd41a17f7335edda441f23fa32e78baab88f12e64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122086410a068a5ac131d76eb9679ada0290a3ffe47e5c24d26323ab4ce21f15384d64736f6c634300080d0033", } // AddressABI is the input ABI used to generate the binding from. @@ -204,7 +506,7 @@ func (_Address *AddressTransactorRaw) Transact(opts *bind.TransactOpts, method s // AddressUpgradeableMetaData contains all meta data concerning the AddressUpgradeable contract. var AddressUpgradeableMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202c6b8e1822db4f974554f11034b0edec9db33a49b7b0cacc647a148f2a41a06064736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220199284fb3ffd3e57045ba78afcd65635f255f3e4b42774bf260491c1b495c4e064736f6c634300080d0033", } // AddressUpgradeableABI is the input ABI used to generate the binding from. @@ -377,7 +679,7 @@ func (_AddressUpgradeable *AddressUpgradeableTransactorRaw) Transact(opts *bind. // AttestationMetaData contains all meta data concerning the Attestation contract. var AttestationMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220328148d376d8cd36305b90ccf18e8a52a8c3b2a30f5fff8ffe0f89b95a576e3d64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122089a7ee9af41c1ca388ec12e23b70ea7aa4690fd8ef84592bf621a254ffabb9e264736f6c634300080d0033", } // AttestationABI is the input ABI used to generate the binding from. @@ -550,7 +852,7 @@ func (_Attestation *AttestationTransactorRaw) Transact(opts *bind.TransactOpts, // AuthMetaData contains all meta data concerning the Auth contract. var AuthMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122086acd960f5c044bc13d8b36301c8528c2a97255c30db32c7c759d4b3673074f064736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122032e213c688910be4d1ee9b920b12d5255ade3dc923f2229f5d3911503e5b4c6064736f6c634300080d0033", } // AuthABI is the input ABI used to generate the binding from. @@ -720,157 +1022,6 @@ func (_Auth *AuthTransactorRaw) Transact(opts *bind.TransactOpts, method string, return _Auth.Contract.contract.Transact(opts, method, params...) } -// AuthManagerMetaData contains all meta data concerning the AuthManager contract. -var AuthManagerMetaData = &bind.MetaData{ - ABI: "[]", -} - -// AuthManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use AuthManagerMetaData.ABI instead. -var AuthManagerABI = AuthManagerMetaData.ABI - -// AuthManager is an auto generated Go binding around an Ethereum contract. -type AuthManager struct { - AuthManagerCaller // Read-only binding to the contract - AuthManagerTransactor // Write-only binding to the contract - AuthManagerFilterer // Log filterer for contract events -} - -// AuthManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type AuthManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type AuthManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type AuthManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type AuthManagerSession struct { - Contract *AuthManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type AuthManagerCallerSession struct { - Contract *AuthManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// AuthManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type AuthManagerTransactorSession struct { - Contract *AuthManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type AuthManagerRaw struct { - Contract *AuthManager // Generic contract binding to access the raw methods on -} - -// AuthManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type AuthManagerCallerRaw struct { - Contract *AuthManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// AuthManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type AuthManagerTransactorRaw struct { - Contract *AuthManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewAuthManager creates a new instance of AuthManager, bound to a specific deployed contract. -func NewAuthManager(address common.Address, backend bind.ContractBackend) (*AuthManager, error) { - contract, err := bindAuthManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &AuthManager{AuthManagerCaller: AuthManagerCaller{contract: contract}, AuthManagerTransactor: AuthManagerTransactor{contract: contract}, AuthManagerFilterer: AuthManagerFilterer{contract: contract}}, nil -} - -// NewAuthManagerCaller creates a new read-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerCaller(address common.Address, caller bind.ContractCaller) (*AuthManagerCaller, error) { - contract, err := bindAuthManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &AuthManagerCaller{contract: contract}, nil -} - -// NewAuthManagerTransactor creates a new write-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*AuthManagerTransactor, error) { - contract, err := bindAuthManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &AuthManagerTransactor{contract: contract}, nil -} - -// NewAuthManagerFilterer creates a new log filterer instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*AuthManagerFilterer, error) { - contract, err := bindAuthManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &AuthManagerFilterer{contract: contract}, nil -} - -// bindAuthManager binds a generic wrapper to an already deployed contract. -func bindAuthManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(AuthManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.AuthManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transact(opts, method, params...) -} - // ContextUpgradeableMetaData contains all meta data concerning the ContextUpgradeable contract. var ContextUpgradeableMetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", @@ -1156,23 +1307,32 @@ func (_ContextUpgradeable *ContextUpgradeableFilterer) ParseInitialized(log type return event, nil } -// ECDSAMetaData contains all meta data concerning the ECDSA contract. -var ECDSAMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220dbd3805c30444ef20f50d292bc1633f9c304334441b3f8fb7dbe952cf4be342964736f6c634300080d0033", -} +// DomainNotaryRegistryMetaData contains all meta data concerning the DomainNotaryRegistry contract. +var DomainNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_trackedDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "9817e315": "allNotaries()", + "c07dc7f5": "getNotary(uint256)", + "8e62e9ef": "notariesAmount()", + }, + Bin: "0x60a060405234801561001057600080fd5b506040516102e73803806102e783398101604081905261002f9161003d565b63ffffffff1660805261006a565b60006020828403121561004f57600080fd5b815163ffffffff8116811461006357600080fd5b9392505050565b608051610265610082600039600050506102656000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207488425b7dac36a7e777e3ea12645cfc70786a290657cd4c09cd3c060cbbbd6864736f6c634300080d0033", +} -// ECDSAABI is the input ABI used to generate the binding from. -// Deprecated: Use ECDSAMetaData.ABI instead. -var ECDSAABI = ECDSAMetaData.ABI +// DomainNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use DomainNotaryRegistryMetaData.ABI instead. +var DomainNotaryRegistryABI = DomainNotaryRegistryMetaData.ABI -// ECDSABin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ECDSAMetaData.Bin instead. -var ECDSABin = ECDSAMetaData.Bin +// Deprecated: Use DomainNotaryRegistryMetaData.Sigs instead. +// DomainNotaryRegistryFuncSigs maps the 4-byte function signature to its string representation. +var DomainNotaryRegistryFuncSigs = DomainNotaryRegistryMetaData.Sigs -// DeployECDSA deploys a new Ethereum contract, binding an instance of ECDSA to it. -func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ECDSA, error) { - parsed, err := ECDSAMetaData.GetAbi() +// DomainNotaryRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use DomainNotaryRegistryMetaData.Bin instead. +var DomainNotaryRegistryBin = DomainNotaryRegistryMetaData.Bin + +// DeployDomainNotaryRegistry deploys a new Ethereum contract, binding an instance of DomainNotaryRegistry to it. +func DeployDomainNotaryRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, _trackedDomain uint32) (common.Address, *types.Transaction, *DomainNotaryRegistry, error) { + parsed, err := DomainNotaryRegistryMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1180,111 +1340,111 @@ func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common. return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ECDSABin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DomainNotaryRegistryBin), backend, _trackedDomain) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil + return address, tx, &DomainNotaryRegistry{DomainNotaryRegistryCaller: DomainNotaryRegistryCaller{contract: contract}, DomainNotaryRegistryTransactor: DomainNotaryRegistryTransactor{contract: contract}, DomainNotaryRegistryFilterer: DomainNotaryRegistryFilterer{contract: contract}}, nil } -// ECDSA is an auto generated Go binding around an Ethereum contract. -type ECDSA struct { - ECDSACaller // Read-only binding to the contract - ECDSATransactor // Write-only binding to the contract - ECDSAFilterer // Log filterer for contract events +// DomainNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type DomainNotaryRegistry struct { + DomainNotaryRegistryCaller // Read-only binding to the contract + DomainNotaryRegistryTransactor // Write-only binding to the contract + DomainNotaryRegistryFilterer // Log filterer for contract events } -// ECDSACaller is an auto generated read-only Go binding around an Ethereum contract. -type ECDSACaller struct { +// DomainNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type DomainNotaryRegistryCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSATransactor is an auto generated write-only Go binding around an Ethereum contract. -type ECDSATransactor struct { +// DomainNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type DomainNotaryRegistryTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSAFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ECDSAFilterer struct { +// DomainNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type DomainNotaryRegistryFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSASession is an auto generated Go binding around an Ethereum contract, +// DomainNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ECDSASession struct { - Contract *ECDSA // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type DomainNotaryRegistrySession struct { + Contract *DomainNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ECDSACallerSession is an auto generated read-only Go binding around an Ethereum contract, +// DomainNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ECDSACallerSession struct { - Contract *ECDSACaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type DomainNotaryRegistryCallerSession struct { + Contract *DomainNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ECDSATransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// DomainNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ECDSATransactorSession struct { - Contract *ECDSATransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type DomainNotaryRegistryTransactorSession struct { + Contract *DomainNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ECDSARaw is an auto generated low-level Go binding around an Ethereum contract. -type ECDSARaw struct { - Contract *ECDSA // Generic contract binding to access the raw methods on +// DomainNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type DomainNotaryRegistryRaw struct { + Contract *DomainNotaryRegistry // Generic contract binding to access the raw methods on } -// ECDSACallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ECDSACallerRaw struct { - Contract *ECDSACaller // Generic read-only contract binding to access the raw methods on +// DomainNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type DomainNotaryRegistryCallerRaw struct { + Contract *DomainNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on } -// ECDSATransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ECDSATransactorRaw struct { - Contract *ECDSATransactor // Generic write-only contract binding to access the raw methods on +// DomainNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type DomainNotaryRegistryTransactorRaw struct { + Contract *DomainNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on } -// NewECDSA creates a new instance of ECDSA, bound to a specific deployed contract. -func NewECDSA(address common.Address, backend bind.ContractBackend) (*ECDSA, error) { - contract, err := bindECDSA(address, backend, backend, backend) +// NewDomainNotaryRegistry creates a new instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistry(address common.Address, backend bind.ContractBackend) (*DomainNotaryRegistry, error) { + contract, err := bindDomainNotaryRegistry(address, backend, backend, backend) if err != nil { return nil, err } - return &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil + return &DomainNotaryRegistry{DomainNotaryRegistryCaller: DomainNotaryRegistryCaller{contract: contract}, DomainNotaryRegistryTransactor: DomainNotaryRegistryTransactor{contract: contract}, DomainNotaryRegistryFilterer: DomainNotaryRegistryFilterer{contract: contract}}, nil } -// NewECDSACaller creates a new read-only instance of ECDSA, bound to a specific deployed contract. -func NewECDSACaller(address common.Address, caller bind.ContractCaller) (*ECDSACaller, error) { - contract, err := bindECDSA(address, caller, nil, nil) +// NewDomainNotaryRegistryCaller creates a new read-only instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*DomainNotaryRegistryCaller, error) { + contract, err := bindDomainNotaryRegistry(address, caller, nil, nil) if err != nil { return nil, err } - return &ECDSACaller{contract: contract}, nil + return &DomainNotaryRegistryCaller{contract: contract}, nil } -// NewECDSATransactor creates a new write-only instance of ECDSA, bound to a specific deployed contract. -func NewECDSATransactor(address common.Address, transactor bind.ContractTransactor) (*ECDSATransactor, error) { - contract, err := bindECDSA(address, nil, transactor, nil) +// NewDomainNotaryRegistryTransactor creates a new write-only instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*DomainNotaryRegistryTransactor, error) { + contract, err := bindDomainNotaryRegistry(address, nil, transactor, nil) if err != nil { return nil, err } - return &ECDSATransactor{contract: contract}, nil + return &DomainNotaryRegistryTransactor{contract: contract}, nil } -// NewECDSAFilterer creates a new log filterer instance of ECDSA, bound to a specific deployed contract. -func NewECDSAFilterer(address common.Address, filterer bind.ContractFilterer) (*ECDSAFilterer, error) { - contract, err := bindECDSA(address, nil, nil, filterer) +// NewDomainNotaryRegistryFilterer creates a new log filterer instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*DomainNotaryRegistryFilterer, error) { + contract, err := bindDomainNotaryRegistry(address, nil, nil, filterer) if err != nil { return nil, err } - return &ECDSAFilterer{contract: contract}, nil + return &DomainNotaryRegistryFilterer{contract: contract}, nil } -// bindECDSA binds a generic wrapper to an already deployed contract. -func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ECDSAABI)) +// bindDomainNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindDomainNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(DomainNotaryRegistryABI)) if err != nil { return nil, err } @@ -1295,258 +1455,418 @@ func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bi // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ECDSA *ECDSARaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ECDSA.Contract.ECDSACaller.contract.Call(opts, result, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ECDSA *ECDSARaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ECDSA.Contract.ECDSATransactor.contract.Transfer(opts) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ECDSA *ECDSARaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ECDSA.Contract.ECDSATransactor.contract.Transact(opts, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ECDSA *ECDSACallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ECDSA.Contract.contract.Call(opts, result, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DomainNotaryRegistry.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ECDSA *ECDSATransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ECDSA.Contract.contract.Transfer(opts) +func (_DomainNotaryRegistry *DomainNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ECDSA.Contract.contract.Transact(opts, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.contract.Transact(opts, method, params...) } -// HeaderMetaData contains all meta data concerning the Header contract. -var HeaderMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202a97cb42977a631ee079605c884e050c7f4591a2244ba2a70bc54d437d5ac88664736f6c634300080d0033", +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) AllNotaries(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "allNotaries") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + } -// HeaderABI is the input ABI used to generate the binding from. -// Deprecated: Use HeaderMetaData.ABI instead. -var HeaderABI = HeaderMetaData.ABI +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) AllNotaries() ([]common.Address, error) { + return _DomainNotaryRegistry.Contract.AllNotaries(&_DomainNotaryRegistry.CallOpts) +} -// HeaderBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HeaderMetaData.Bin instead. -var HeaderBin = HeaderMetaData.Bin +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) AllNotaries() ([]common.Address, error) { + return _DomainNotaryRegistry.Contract.AllNotaries(&_DomainNotaryRegistry.CallOpts) +} -// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. -func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { - parsed, err := HeaderMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "getNotary", _index) - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) if err != nil { - return common.Address{}, nil, nil, err + return *new(common.Address), err } - return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil -} -// Header is an auto generated Go binding around an Ethereum contract. -type Header struct { - HeaderCaller // Read-only binding to the contract - HeaderTransactor // Write-only binding to the contract - HeaderFilterer // Log filterer for contract events -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err -// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. -type HeaderCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HeaderTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) GetNotary(_index *big.Int) (common.Address, error) { + return _DomainNotaryRegistry.Contract.GetNotary(&_DomainNotaryRegistry.CallOpts, _index) } -// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HeaderFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) GetNotary(_index *big.Int) (common.Address, error) { + return _DomainNotaryRegistry.Contract.GetNotary(&_DomainNotaryRegistry.CallOpts, _index) } -// HeaderSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type HeaderSession struct { - Contract *Header // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) NotariesAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "notariesAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type HeaderCallerSession struct { - Contract *HeaderCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) NotariesAmount() (*big.Int, error) { + return _DomainNotaryRegistry.Contract.NotariesAmount(&_DomainNotaryRegistry.CallOpts) } -// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type HeaderTransactorSession struct { - Contract *HeaderTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) NotariesAmount() (*big.Int, error) { + return _DomainNotaryRegistry.Contract.NotariesAmount(&_DomainNotaryRegistry.CallOpts) } -// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. -type HeaderRaw struct { - Contract *Header // Generic contract binding to access the raw methods on +// DomainNotaryRegistryDomainNotaryAddedIterator is returned from FilterDomainNotaryAdded and is used to iterate over the raw logs and unpacked data for DomainNotaryAdded events raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryAddedIterator struct { + Event *DomainNotaryRegistryDomainNotaryAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HeaderCallerRaw struct { - Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HeaderTransactorRaw struct { - Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Error() error { + return it.fail } -// NewHeader creates a new instance of Header, bound to a specific deployed contract. -func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { - contract, err := bindHeader(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. -func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { - contract, err := bindHeader(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &HeaderCaller{contract: contract}, nil +// DomainNotaryRegistryDomainNotaryAdded represents a DomainNotaryAdded event raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryAdded struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. -func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { - contract, err := bindHeader(address, nil, transactor, nil) +// FilterDomainNotaryAdded is a free log retrieval operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) FilterDomainNotaryAdded(opts *bind.FilterOpts) (*DomainNotaryRegistryDomainNotaryAddedIterator, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.FilterLogs(opts, "DomainNotaryAdded") if err != nil { return nil, err } - return &HeaderTransactor{contract: contract}, nil + return &DomainNotaryRegistryDomainNotaryAddedIterator{contract: _DomainNotaryRegistry.contract, event: "DomainNotaryAdded", logs: logs, sub: sub}, nil } -// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. -func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { - contract, err := bindHeader(address, nil, nil, filterer) +// WatchDomainNotaryAdded is a free log subscription operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *DomainNotaryRegistryDomainNotaryAdded) (event.Subscription, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.WatchLogs(opts, "DomainNotaryAdded") if err != nil { return nil, err } - return &HeaderFilterer{contract: contract}, nil -} - -// bindHeader binds a generic wrapper to an already deployed contract. -func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HeaderABI)) - if err != nil { + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DomainNotaryRegistryDomainNotaryAdded) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDomainNotaryAdded is a log parse operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) ParseDomainNotaryAdded(log types.Log) (*DomainNotaryRegistryDomainNotaryAdded, error) { + event := new(DomainNotaryRegistryDomainNotaryAdded) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + event.Raw = log + return event, nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) +// DomainNotaryRegistryDomainNotaryRemovedIterator is returned from FilterDomainNotaryRemoved and is used to iterate over the raw logs and unpacked data for DomainNotaryRemoved events raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryRemovedIterator struct { + Event *DomainNotaryRegistryDomainNotaryRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transfer(opts) +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Error() error { + return it.fail } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.contract.Call(opts, result, method, params...) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.contract.Transfer(opts) +// DomainNotaryRegistryDomainNotaryRemoved represents a DomainNotaryRemoved event raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryRemoved struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.contract.Transact(opts, method, params...) +// FilterDomainNotaryRemoved is a free log retrieval operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*DomainNotaryRegistryDomainNotaryRemovedIterator, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.FilterLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return &DomainNotaryRegistryDomainNotaryRemovedIterator{contract: _DomainNotaryRegistry.contract, event: "DomainNotaryRemoved", logs: logs, sub: sub}, nil } -// HomeMetaData contains all meta data concerning the Home contract. -var HomeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enumHome.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "522ae002": "MAX_MESSAGE_BODY_BYTES()", - "ffa1ad74": "VERSION()", - "06661abd": "count()", - "f7560e40": "dispatch(uint32,bytes32,uint32,bytes,bytes)", - "7ea97f40": "historicalRoots(uint256)", - "0afe7f90": "improperAttestation(bytes)", - "c4d66de8": "initialize(address)", - "8d3638f4": "localDomain()", - "affed0e0": "nonce()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "ebf0c717": "root()", - "b7bc563e": "setSystemMessenger(address)", - "9d54f419": "setUpdater(address)", - "9776120e": "setUpdaterManager(address)", - "c19d93fb": "state()", - "36e104de": "suggestUpdate()", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "fd54b228": "tree()", - "df034cd0": "updater()", - "9df6c8e1": "updaterManager()", - }, - Bin: "0x60a06040523480156200001157600080fd5b50604051620036d9380380620036d9833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b60805161363d6200009c6000396000818161025e01528181610d9c01526117a3015261363d6000f3fe6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220f643bf9e6b98bca92cef57a0e66845240591081bb4bd1964fd1a0fae6855bcdb64736f6c634300080d0033", +// WatchDomainNotaryRemoved is a free log subscription operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *DomainNotaryRegistryDomainNotaryRemoved) (event.Subscription, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.WatchLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DomainNotaryRegistryDomainNotaryRemoved) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// HomeABI is the input ABI used to generate the binding from. -// Deprecated: Use HomeMetaData.ABI instead. -var HomeABI = HomeMetaData.ABI +// ParseDomainNotaryRemoved is a log parse operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) ParseDomainNotaryRemoved(log types.Log) (*DomainNotaryRegistryDomainNotaryRemoved, error) { + event := new(DomainNotaryRegistryDomainNotaryRemoved) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} -// Deprecated: Use HomeMetaData.Sigs instead. -// HomeFuncSigs maps the 4-byte function signature to its string representation. -var HomeFuncSigs = HomeMetaData.Sigs +// ECDSAMetaData contains all meta data concerning the ECDSA contract. +var ECDSAMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220aafb18d6c55b3b9fb8db22621ae0b6eb0d4658287bd164c4c73e5ac0a3b48f0264736f6c634300080d0033", +} -// HomeBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HomeMetaData.Bin instead. -var HomeBin = HomeMetaData.Bin +// ECDSAABI is the input ABI used to generate the binding from. +// Deprecated: Use ECDSAMetaData.ABI instead. +var ECDSAABI = ECDSAMetaData.ABI -// DeployHome deploys a new Ethereum contract, binding an instance of Home to it. -func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *Home, error) { - parsed, err := HomeMetaData.GetAbi() +// ECDSABin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ECDSAMetaData.Bin instead. +var ECDSABin = ECDSAMetaData.Bin + +// DeployECDSA deploys a new Ethereum contract, binding an instance of ECDSA to it. +func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ECDSA, error) { + parsed, err := ECDSAMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1554,111 +1874,111 @@ func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDom return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HomeBin), backend, _localDomain) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ECDSABin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil + return address, tx, &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil } -// Home is an auto generated Go binding around an Ethereum contract. -type Home struct { - HomeCaller // Read-only binding to the contract - HomeTransactor // Write-only binding to the contract - HomeFilterer // Log filterer for contract events +// ECDSA is an auto generated Go binding around an Ethereum contract. +type ECDSA struct { + ECDSACaller // Read-only binding to the contract + ECDSATransactor // Write-only binding to the contract + ECDSAFilterer // Log filterer for contract events } -// HomeCaller is an auto generated read-only Go binding around an Ethereum contract. -type HomeCaller struct { +// ECDSACaller is an auto generated read-only Go binding around an Ethereum contract. +type ECDSACaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HomeTransactor struct { +// ECDSATransactor is an auto generated write-only Go binding around an Ethereum contract. +type ECDSATransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HomeFilterer struct { +// ECDSAFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ECDSAFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeSession is an auto generated Go binding around an Ethereum contract, +// ECDSASession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type HomeSession struct { - Contract *Home // Generic contract binding to set the session for +type ECDSASession struct { + Contract *ECDSA // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// ECDSACallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type HomeCallerSession struct { - Contract *HomeCaller // Generic contract caller binding to set the session for +type ECDSACallerSession struct { + Contract *ECDSACaller // Generic contract caller binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session } -// HomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// ECDSATransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type HomeTransactorSession struct { - Contract *HomeTransactor // Generic contract transactor binding to set the session for +type ECDSATransactorSession struct { + Contract *ECDSATransactor // Generic contract transactor binding to set the session for TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HomeRaw is an auto generated low-level Go binding around an Ethereum contract. -type HomeRaw struct { - Contract *Home // Generic contract binding to access the raw methods on -} - -// HomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HomeCallerRaw struct { - Contract *HomeCaller // Generic read-only contract binding to access the raw methods on +// ECDSARaw is an auto generated low-level Go binding around an Ethereum contract. +type ECDSARaw struct { + Contract *ECDSA // Generic contract binding to access the raw methods on } -// HomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HomeTransactorRaw struct { - Contract *HomeTransactor // Generic write-only contract binding to access the raw methods on +// ECDSACallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ECDSACallerRaw struct { + Contract *ECDSACaller // Generic read-only contract binding to access the raw methods on } -// NewHome creates a new instance of Home, bound to a specific deployed contract. -func NewHome(address common.Address, backend bind.ContractBackend) (*Home, error) { - contract, err := bindHome(address, backend, backend, backend) +// ECDSATransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ECDSATransactorRaw struct { + Contract *ECDSATransactor // Generic write-only contract binding to access the raw methods on +} + +// NewECDSA creates a new instance of ECDSA, bound to a specific deployed contract. +func NewECDSA(address common.Address, backend bind.ContractBackend) (*ECDSA, error) { + contract, err := bindECDSA(address, backend, backend, backend) if err != nil { return nil, err } - return &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil + return &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil } -// NewHomeCaller creates a new read-only instance of Home, bound to a specific deployed contract. -func NewHomeCaller(address common.Address, caller bind.ContractCaller) (*HomeCaller, error) { - contract, err := bindHome(address, caller, nil, nil) +// NewECDSACaller creates a new read-only instance of ECDSA, bound to a specific deployed contract. +func NewECDSACaller(address common.Address, caller bind.ContractCaller) (*ECDSACaller, error) { + contract, err := bindECDSA(address, caller, nil, nil) if err != nil { return nil, err } - return &HomeCaller{contract: contract}, nil + return &ECDSACaller{contract: contract}, nil } -// NewHomeTransactor creates a new write-only instance of Home, bound to a specific deployed contract. -func NewHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*HomeTransactor, error) { - contract, err := bindHome(address, nil, transactor, nil) +// NewECDSATransactor creates a new write-only instance of ECDSA, bound to a specific deployed contract. +func NewECDSATransactor(address common.Address, transactor bind.ContractTransactor) (*ECDSATransactor, error) { + contract, err := bindECDSA(address, nil, transactor, nil) if err != nil { return nil, err } - return &HomeTransactor{contract: contract}, nil + return &ECDSATransactor{contract: contract}, nil } -// NewHomeFilterer creates a new log filterer instance of Home, bound to a specific deployed contract. -func NewHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*HomeFilterer, error) { - contract, err := bindHome(address, nil, nil, filterer) +// NewECDSAFilterer creates a new log filterer instance of ECDSA, bound to a specific deployed contract. +func NewECDSAFilterer(address common.Address, filterer bind.ContractFilterer) (*ECDSAFilterer, error) { + contract, err := bindECDSA(address, nil, nil, filterer) if err != nil { return nil, err } - return &HomeFilterer{contract: contract}, nil + return &ECDSAFilterer{contract: contract}, nil } -// bindHome binds a generic wrapper to an already deployed contract. -func bindHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HomeABI)) +// bindECDSA binds a generic wrapper to an already deployed contract. +func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ECDSAABI)) if err != nil { return nil, err } @@ -1669,370 +1989,432 @@ func bindHome(address common.Address, caller bind.ContractCaller, transactor bin // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Home *HomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Home.Contract.HomeCaller.contract.Call(opts, result, method, params...) +func (_ECDSA *ECDSARaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ECDSA.Contract.ECDSACaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Home *HomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.Contract.HomeTransactor.contract.Transfer(opts) +func (_ECDSA *ECDSARaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ECDSA.Contract.ECDSATransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Home *HomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Home.Contract.HomeTransactor.contract.Transact(opts, method, params...) +func (_ECDSA *ECDSARaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ECDSA.Contract.ECDSATransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Home *HomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Home.Contract.contract.Call(opts, result, method, params...) +func (_ECDSA *ECDSACallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ECDSA.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Home *HomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.Contract.contract.Transfer(opts) +func (_ECDSA *ECDSATransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ECDSA.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Home *HomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Home.Contract.contract.Transact(opts, method, params...) +func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ECDSA.Contract.contract.Transact(opts, method, params...) } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeCaller) MAXMESSAGEBODYBYTES(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "MAX_MESSAGE_BODY_BYTES") +// EnumerableSetMetaData contains all meta data concerning the EnumerableSet contract. +var EnumerableSetMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a3729d0d21bb0e65b1bfc3d61992d75263f9f4ab8d70965923c2ea2ff131867964736f6c634300080d0033", +} - if err != nil { - return *new(*big.Int), err - } +// EnumerableSetABI is the input ABI used to generate the binding from. +// Deprecated: Use EnumerableSetMetaData.ABI instead. +var EnumerableSetABI = EnumerableSetMetaData.ABI - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) +// EnumerableSetBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use EnumerableSetMetaData.Bin instead. +var EnumerableSetBin = EnumerableSetMetaData.Bin - return out0, err +// DeployEnumerableSet deploys a new Ethereum contract, binding an instance of EnumerableSet to it. +func DeployEnumerableSet(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *EnumerableSet, error) { + parsed, err := EnumerableSetMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EnumerableSetBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { - return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) +// EnumerableSet is an auto generated Go binding around an Ethereum contract. +type EnumerableSet struct { + EnumerableSetCaller // Read-only binding to the contract + EnumerableSetTransactor // Write-only binding to the contract + EnumerableSetFilterer // Log filterer for contract events } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeCallerSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { - return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) +// EnumerableSetCaller is an auto generated read-only Go binding around an Ethereum contract. +type EnumerableSetCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeCaller) VERSION(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "VERSION") +// EnumerableSetTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EnumerableSetTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - if err != nil { - return *new(uint8), err - } +// EnumerableSetFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EnumerableSetFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) +// EnumerableSetSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type EnumerableSetSession struct { + Contract *EnumerableSet // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - return out0, err +// EnumerableSetCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type EnumerableSetCallerSession struct { + Contract *EnumerableSetCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} +// EnumerableSetTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type EnumerableSetTransactorSession struct { + Contract *EnumerableSetTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeSession) VERSION() (uint8, error) { - return _Home.Contract.VERSION(&_Home.CallOpts) +// EnumerableSetRaw is an auto generated low-level Go binding around an Ethereum contract. +type EnumerableSetRaw struct { + Contract *EnumerableSet // Generic contract binding to access the raw methods on } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeCallerSession) VERSION() (uint8, error) { - return _Home.Contract.VERSION(&_Home.CallOpts) +// EnumerableSetCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EnumerableSetCallerRaw struct { + Contract *EnumerableSetCaller // Generic read-only contract binding to access the raw methods on } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeCaller) Count(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "count") +// EnumerableSetTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EnumerableSetTransactorRaw struct { + Contract *EnumerableSetTransactor // Generic write-only contract binding to access the raw methods on +} +// NewEnumerableSet creates a new instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSet(address common.Address, backend bind.ContractBackend) (*EnumerableSet, error) { + contract, err := bindEnumerableSet(address, backend, backend, backend) if err != nil { - return *new(*big.Int), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - + return &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeSession) Count() (*big.Int, error) { - return _Home.Contract.Count(&_Home.CallOpts) +// NewEnumerableSetCaller creates a new read-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetCaller(address common.Address, caller bind.ContractCaller) (*EnumerableSetCaller, error) { + contract, err := bindEnumerableSet(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EnumerableSetCaller{contract: contract}, nil } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeCallerSession) Count() (*big.Int, error) { - return _Home.Contract.Count(&_Home.CallOpts) +// NewEnumerableSetTransactor creates a new write-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetTransactor(address common.Address, transactor bind.ContractTransactor) (*EnumerableSetTransactor, error) { + contract, err := bindEnumerableSet(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EnumerableSetTransactor{contract: contract}, nil } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "historicalRoots", arg0) +// NewEnumerableSetFilterer creates a new log filterer instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetFilterer(address common.Address, filterer bind.ContractFilterer) (*EnumerableSetFilterer, error) { + contract, err := bindEnumerableSet(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EnumerableSetFilterer{contract: contract}, nil +} +// bindEnumerableSet binds a generic wrapper to an already deployed contract. +func bindEnumerableSet(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(EnumerableSetABI)) if err != nil { - return *new([32]byte), err + return nil, err } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EnumerableSet *EnumerableSetRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.EnumerableSetCaller.contract.Call(opts, result, method, params...) +} - return out0, err +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EnumerableSet *EnumerableSetRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transfer(opts) +} +// Transact invokes the (paid) contract method with params as input values. +func (_EnumerableSet *EnumerableSetRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transact(opts, method, params...) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EnumerableSet *EnumerableSetCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.contract.Call(opts, result, method, params...) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EnumerableSet *EnumerableSetTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transfer(opts) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "localDomain") +// Transact invokes the (paid) contract method with params as input values. +func (_EnumerableSet *EnumerableSetTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transact(opts, method, params...) +} + +// GuardRegistryMetaData contains all meta data concerning the GuardRegistry contract. +var GuardRegistryMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "9fe03fa2": "allGuards()", + "629ddf69": "getGuard(uint256)", + "246c2449": "guardsAmount()", + }, + Bin: "0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220f595624ec1951ab2c915d6da09033cc65e8a9add26d338c03bc345f95bdabed964736f6c634300080d0033", +} + +// GuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use GuardRegistryMetaData.ABI instead. +var GuardRegistryABI = GuardRegistryMetaData.ABI +// Deprecated: Use GuardRegistryMetaData.Sigs instead. +// GuardRegistryFuncSigs maps the 4-byte function signature to its string representation. +var GuardRegistryFuncSigs = GuardRegistryMetaData.Sigs + +// GuardRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GuardRegistryMetaData.Bin instead. +var GuardRegistryBin = GuardRegistryMetaData.Bin + +// DeployGuardRegistry deploys a new Ethereum contract, binding an instance of GuardRegistry to it. +func DeployGuardRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GuardRegistry, error) { + parsed, err := GuardRegistryMetaData.GetAbi() if err != nil { - return *new(uint32), err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GuardRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil +} - return out0, err +// GuardRegistry is an auto generated Go binding around an Ethereum contract. +type GuardRegistry struct { + GuardRegistryCaller // Read-only binding to the contract + GuardRegistryTransactor // Write-only binding to the contract + GuardRegistryFilterer // Log filterer for contract events +} +// GuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type GuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeSession) LocalDomain() (uint32, error) { - return _Home.Contract.LocalDomain(&_Home.CallOpts) +// GuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeCallerSession) LocalDomain() (uint32, error) { - return _Home.Contract.LocalDomain(&_Home.CallOpts) +// GuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeCaller) Nonce(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "nonce") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) +// GuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GuardRegistrySession struct { + Contract *GuardRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - return out0, err +// GuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type GuardRegistryCallerSession struct { + Contract *GuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} +// GuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type GuardRegistryTransactorSession struct { + Contract *GuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeSession) Nonce() (uint32, error) { - return _Home.Contract.Nonce(&_Home.CallOpts) +// GuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type GuardRegistryRaw struct { + Contract *GuardRegistry // Generic contract binding to access the raw methods on } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeCallerSession) Nonce() (uint32, error) { - return _Home.Contract.Nonce(&_Home.CallOpts) +// GuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GuardRegistryCallerRaw struct { + Contract *GuardRegistryCaller // Generic read-only contract binding to access the raw methods on } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "owner") +// GuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GuardRegistryTransactorRaw struct { + Contract *GuardRegistryTransactor // Generic write-only contract binding to access the raw methods on +} +// NewGuardRegistry creates a new instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistry(address common.Address, backend bind.ContractBackend) (*GuardRegistry, error) { + contract, err := bindGuardRegistry(address, backend, backend, backend) if err != nil { - return *new(common.Address), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - + return &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeSession) Owner() (common.Address, error) { - return _Home.Contract.Owner(&_Home.CallOpts) +// NewGuardRegistryCaller creates a new read-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*GuardRegistryCaller, error) { + contract, err := bindGuardRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &GuardRegistryCaller{contract: contract}, nil } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeCallerSession) Owner() (common.Address, error) { - return _Home.Contract.Owner(&_Home.CallOpts) +// NewGuardRegistryTransactor creates a new write-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*GuardRegistryTransactor, error) { + contract, err := bindGuardRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &GuardRegistryTransactor{contract: contract}, nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeCaller) Root(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "root") - +// NewGuardRegistryFilterer creates a new log filterer instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*GuardRegistryFilterer, error) { + contract, err := bindGuardRegistry(address, nil, nil, filterer) if err != nil { - return *new([32]byte), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - + return &GuardRegistryFilterer{contract: contract}, nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeSession) Root() ([32]byte, error) { - return _Home.Contract.Root(&_Home.CallOpts) +// bindGuardRegistry binds a generic wrapper to an already deployed contract. +func bindGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(GuardRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeCallerSession) Root() ([32]byte, error) { - return _Home.Contract.Root(&_Home.CallOpts) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GuardRegistry *GuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.GuardRegistryCaller.contract.Call(opts, result, method, params...) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeCaller) State(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "state") - - if err != nil { - return *new(uint8), err - } - - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GuardRegistry *GuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transfer(opts) +} - return out0, err +// Transact invokes the (paid) contract method with params as input values. +func (_GuardRegistry *GuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transact(opts, method, params...) +} +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GuardRegistry *GuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.contract.Call(opts, result, method, params...) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeSession) State() (uint8, error) { - return _Home.Contract.State(&_Home.CallOpts) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GuardRegistry *GuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transfer(opts) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeCallerSession) State() (uint8, error) { - return _Home.Contract.State(&_Home.CallOpts) +// Transact invokes the (paid) contract method with params as input values. +func (_GuardRegistry *GuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transact(opts, method, params...) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeCaller) SuggestUpdate(opts *bind.CallOpts) (struct { - Nonce uint32 - Root [32]byte -}, error) { +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "suggestUpdate") + err := _GuardRegistry.contract.Call(opts, &out, "allGuards") - outstruct := new(struct { - Nonce uint32 - Root [32]byte - }) if err != nil { - return *outstruct, err + return *new([]common.Address), err } - outstruct.Nonce = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - return *outstruct, err + return out0, err } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeSession) SuggestUpdate() (struct { - Nonce uint32 - Root [32]byte -}, error) { - return _Home.Contract.SuggestUpdate(&_Home.CallOpts) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistrySession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeCallerSession) SuggestUpdate() (struct { - Nonce uint32 - Root [32]byte -}, error) { - return _Home.Contract.SuggestUpdate(&_Home.CallOpts) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCallerSession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "systemMessenger") + err := _GuardRegistry.contract.Call(opts, &out, "getGuard", _index) if err != nil { return *new(common.Address), err @@ -2044,26 +2426,26 @@ func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, e } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeSession) SystemMessenger() (common.Address, error) { - return _Home.Contract.SystemMessenger(&_Home.CallOpts) +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistrySession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeCallerSession) SystemMessenger() (common.Address, error) { - return _Home.Contract.SystemMessenger(&_Home.CallOpts) +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "tree") + err := _GuardRegistry.contract.Call(opts, &out, "guardsAmount") if err != nil { return *new(*big.Int), err @@ -2075,253 +2457,157 @@ func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeSession) Tree() (*big.Int, error) { - return _Home.Contract.Tree(&_Home.CallOpts) +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistrySession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeCallerSession) Tree() (*big.Int, error) { - return _Home.Contract.Tree(&_Home.CallOpts) +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCallerSession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "updater") +// GuardRegistryGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the GuardRegistry contract. +type GuardRegistryGuardAddedIterator struct { + Event *GuardRegistryGuardAdded // Event containing the contract specifics and raw log - if err != nil { - return *new(common.Address), err + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GuardRegistryGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - return out0, err + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GuardRegistryGuardAddedIterator) Error() error { + return it.fail } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeSession) Updater() (common.Address, error) { - return _Home.Contract.Updater(&_Home.CallOpts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardRegistryGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeCallerSession) Updater() (common.Address, error) { - return _Home.Contract.Updater(&_Home.CallOpts) +// GuardRegistryGuardAdded represents a GuardAdded event raised by the GuardRegistry contract. +type GuardRegistryGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeCaller) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "updaterManager") +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*GuardRegistryGuardAddedIterator, error) { + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardAdded") if err != nil { - return *new(common.Address), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - + return &GuardRegistryGuardAddedIterator{contract: _GuardRegistry.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeSession) UpdaterManager() (common.Address, error) { - return _Home.Contract.UpdaterManager(&_Home.CallOpts) -} - -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. -// -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeCallerSession) UpdaterManager() (common.Address, error) { - return _Home.Contract.UpdaterManager(&_Home.CallOpts) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeTransactor) Dispatch(opts *bind.TransactOpts, _destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "dispatch", _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeTransactorSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeTransactor) ImproperAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "improperAttestation", _attestation) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { - return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeTransactorSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { - return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeTransactor) Initialize(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "initialize", _updaterManager) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeTransactorSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeSession) RenounceOwnership() (*types.Transaction, error) { - return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setSystemMessenger", _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setUpdater", _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeTransactor) SetUpdaterManager(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setUpdaterManager", _updaterManager) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeTransactorSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) -} +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardAdded) (event.Subscription, error) { -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "transferOwnership", newOwner) -} + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardAdded(log types.Log) (*GuardRegistryGuardAdded, error) { + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// HomeDispatchIterator is returned from FilterDispatch and is used to iterate over the raw logs and unpacked data for Dispatch events raised by the Home contract. -type HomeDispatchIterator struct { - Event *HomeDispatch // Event containing the contract specifics and raw log +// GuardRegistryGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the GuardRegistry contract. +type GuardRegistryGuardRemovedIterator struct { + Event *GuardRegistryGuardRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2335,7 +2621,7 @@ type HomeDispatchIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeDispatchIterator) Next() bool { +func (it *GuardRegistryGuardRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2344,7 +2630,7 @@ func (it *HomeDispatchIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeDispatch) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2359,7 +2645,7 @@ func (it *HomeDispatchIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeDispatch) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2375,71 +2661,41 @@ func (it *HomeDispatchIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeDispatchIterator) Error() error { +func (it *GuardRegistryGuardRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeDispatchIterator) Close() error { +func (it *GuardRegistryGuardRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeDispatch represents a Dispatch event raised by the Home contract. -type HomeDispatch struct { - MessageHash [32]byte - LeafIndex *big.Int - DestinationAndNonce uint64 - Tips []byte - Message []byte - Raw types.Log // Blockchain specific contextual infos +// GuardRegistryGuardRemoved represents a GuardRemoved event raised by the GuardRegistry contract. +type GuardRegistryGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterDispatch is a free log retrieval operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (*HomeDispatchIterator, error) { - - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) - } - var leafIndexRule []interface{} - for _, leafIndexItem := range leafIndex { - leafIndexRule = append(leafIndexRule, leafIndexItem) - } - var destinationAndNonceRule []interface{} - for _, destinationAndNonceItem := range destinationAndNonce { - destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) - } +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*GuardRegistryGuardRemovedIterator, error) { - logs, sub, err := _Home.contract.FilterLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardRemoved") if err != nil { return nil, err } - return &HomeDispatchIterator{contract: _Home.contract, event: "Dispatch", logs: logs, sub: sub}, nil + return &GuardRegistryGuardRemovedIterator{contract: _GuardRegistry.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil } -// WatchDispatch is a free log subscription operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *HomeDispatch, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (event.Subscription, error) { - - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) - } - var leafIndexRule []interface{} - for _, leafIndexItem := range leafIndex { - leafIndexRule = append(leafIndexRule, leafIndexItem) - } - var destinationAndNonceRule []interface{} - for _, destinationAndNonceItem := range destinationAndNonce { - destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) - } +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardRemoved) (event.Subscription, error) { - logs, sub, err := _Home.contract.WatchLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardRemoved") if err != nil { return nil, err } @@ -2449,8 +2705,8 @@ func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *Home select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeDispatch) - if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return err } event.Raw = log @@ -2471,1298 +2727,944 @@ func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *Home }), nil } -// ParseDispatch is a log parse operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) ParseDispatch(log types.Log) (*HomeDispatch, error) { - event := new(HomeDispatch) - if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardRemoved(log types.Log) (*GuardRegistryGuardRemoved, error) { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeImproperAttestationIterator is returned from FilterImproperAttestation and is used to iterate over the raw logs and unpacked data for ImproperAttestation events raised by the Home contract. -type HomeImproperAttestationIterator struct { - Event *HomeImproperAttestation // Event containing the contract specifics and raw log +// HeaderMetaData contains all meta data concerning the Header contract. +var HeaderMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208a54bcee6726d4c5d88de93bea39c64ed524c1b0078615e63008071f9e18931964736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// HeaderABI is the input ABI used to generate the binding from. +// Deprecated: Use HeaderMetaData.ABI instead. +var HeaderABI = HeaderMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// HeaderBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HeaderMetaData.Bin instead. +var HeaderBin = HeaderMetaData.Bin -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeImproperAttestationIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. +func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { + parsed, err := HeaderMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeImproperAttestation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeImproperAttestation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } + return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeImproperAttestationIterator) Error() error { - return it.fail +// Header is an auto generated Go binding around an Ethereum contract. +type Header struct { + HeaderCaller // Read-only binding to the contract + HeaderTransactor // Write-only binding to the contract + HeaderFilterer // Log filterer for contract events } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeImproperAttestationIterator) Close() error { - it.sub.Unsubscribe() - return nil +// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. +type HeaderCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeImproperAttestation represents a ImproperAttestation event raised by the Home contract. -type HomeImproperAttestation struct { - Updater common.Address - Attestation []byte - Raw types.Log // Blockchain specific contextual infos +// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HeaderTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) FilterImproperAttestation(opts *bind.FilterOpts) (*HomeImproperAttestationIterator, error) { +// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HeaderFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs, sub, err := _Home.contract.FilterLogs(opts, "ImproperAttestation") +// HeaderSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type HeaderSession struct { + Contract *Header // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type HeaderCallerSession struct { + Contract *HeaderCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type HeaderTransactorSession struct { + Contract *HeaderTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. +type HeaderRaw struct { + Contract *Header // Generic contract binding to access the raw methods on +} + +// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HeaderCallerRaw struct { + Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on +} + +// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HeaderTransactorRaw struct { + Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewHeader creates a new instance of Header, bound to a specific deployed contract. +func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { + contract, err := bindHeader(address, backend, backend, backend) if err != nil { return nil, err } - return &HomeImproperAttestationIterator{contract: _Home.contract, event: "ImproperAttestation", logs: logs, sub: sub}, nil + return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// WatchImproperAttestation is a free log subscription operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *HomeImproperAttestation) (event.Subscription, error) { - - logs, sub, err := _Home.contract.WatchLogs(opts, "ImproperAttestation") +// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. +func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { + contract, err := bindHeader(address, caller, nil, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeImproperAttestation) - if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { - return err - } - event.Raw = log + return &HeaderCaller{contract: contract}, nil +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. +func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { + contract, err := bindHeader(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &HeaderTransactor{contract: contract}, nil } -// ParseImproperAttestation is a log parse operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) ParseImproperAttestation(log types.Log) (*HomeImproperAttestation, error) { - event := new(HomeImproperAttestation) - if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { +// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. +func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { + contract, err := bindHeader(address, nil, nil, filterer) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &HeaderFilterer{contract: contract}, nil } -// HomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Home contract. -type HomeInitializedIterator struct { - Event *HomeInitialized // Event containing the contract specifics and raw log +// bindHeader binds a generic wrapper to an already deployed contract. +func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HeaderABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transfer(opts) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transact invokes the (paid) contract method with params as input values. +func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.contract.Call(opts, result, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeInitializedIterator) Error() error { - return it.fail +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.contract.Transfer(opts) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transact invokes the (paid) contract method with params as input values. +func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.contract.Transact(opts, method, params...) } -// HomeInitialized represents a Initialized event raised by the Home contract. -type HomeInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// HomeMetaData contains all meta data concerning the Home contract. +var HomeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enumHome.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "522ae002": "MAX_MESSAGE_BODY_BYTES()", + "ffa1ad74": "VERSION()", + "9fe03fa2": "allGuards()", + "9817e315": "allNotaries()", + "06661abd": "count()", + "f7560e40": "dispatch(uint32,bytes32,uint32,bytes,bytes)", + "629ddf69": "getGuard(uint256)", + "c07dc7f5": "getNotary(uint256)", + "246c2449": "guardsAmount()", + "7ea97f40": "historicalRoots(uint256)", + "0afe7f90": "improperAttestation(bytes)", + "c4d66de8": "initialize(address)", + "8d3638f4": "localDomain()", + "affed0e0": "nonce()", + "8e62e9ef": "notariesAmount()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "ebf0c717": "root()", + "b7bc563e": "setSystemMessenger(address)", + "9d54f419": "setUpdater(address)", + "9776120e": "setUpdaterManager(address)", + "c19d93fb": "state()", + "36e104de": "suggestUpdate()", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + "fd54b228": "tree()", + "9df6c8e1": "updaterManager()", + }, + Bin: "0x60c06040523480156200001157600080fd5b50604051620038c7380380620038c7833981016040819052620000349162000048565b63ffffffff16608081905260a05262000077565b6000602082840312156200005b57600080fd5b815163ffffffff811681146200007057600080fd5b9392505050565b60805160a051613823620000a460003960006118a70152600081816102ef0152610ea501526138236000f3fe6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea26469706673582212204b3dd278e50546afd875e58a557a694ab8bd8303e5d2310e202d5e16d06d649b64736f6c634300080d0033", } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*HomeInitializedIterator, error) { +// HomeABI is the input ABI used to generate the binding from. +// Deprecated: Use HomeMetaData.ABI instead. +var HomeABI = HomeMetaData.ABI - logs, sub, err := _Home.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return &HomeInitializedIterator{contract: _Home.contract, event: "Initialized", logs: logs, sub: sub}, nil -} +// Deprecated: Use HomeMetaData.Sigs instead. +// HomeFuncSigs maps the 4-byte function signature to its string representation. +var HomeFuncSigs = HomeMetaData.Sigs -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *HomeInitialized) (event.Subscription, error) { +// HomeBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HomeMetaData.Bin instead. +var HomeBin = HomeMetaData.Bin - logs, sub, err := _Home.contract.WatchLogs(opts, "Initialized") +// DeployHome deploys a new Ethereum contract, binding an instance of Home to it. +func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *Home, error) { + parsed, err := HomeMetaData.GetAbi() if err != nil { - return nil, err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeInitialized) - if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HomeBin), backend, _localDomain) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) ParseInitialized(log types.Log) (*HomeInitialized, error) { - event := new(HomeInitialized) - if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Home is an auto generated Go binding around an Ethereum contract. +type Home struct { + HomeCaller // Read-only binding to the contract + HomeTransactor // Write-only binding to the contract + HomeFilterer // Log filterer for contract events } -// HomeNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the Home contract. -type HomeNewUpdaterIterator struct { - Event *HomeNewUpdater // Event containing the contract specifics and raw log +// HomeCaller is an auto generated read-only Go binding around an Ethereum contract. +type HomeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// HomeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HomeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// HomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HomeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// HomeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type HomeSession struct { + Contract *Home // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// HomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type HomeCallerSession struct { + Contract *HomeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// HomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type HomeTransactorSession struct { + Contract *HomeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeNewUpdaterIterator) Error() error { - return it.fail +// HomeRaw is an auto generated low-level Go binding around an Ethereum contract. +type HomeRaw struct { + Contract *Home // Generic contract binding to access the raw methods on } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// HomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HomeCallerRaw struct { + Contract *HomeCaller // Generic read-only contract binding to access the raw methods on } -// HomeNewUpdater represents a NewUpdater event raised by the Home contract. -type HomeNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// HomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HomeTransactorRaw struct { + Contract *HomeTransactor // Generic write-only contract binding to access the raw methods on } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*HomeNewUpdaterIterator, error) { +// NewHome creates a new instance of Home, bound to a specific deployed contract. +func NewHome(address common.Address, backend bind.ContractBackend) (*Home, error) { + contract, err := bindHome(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil +} - logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdater") +// NewHomeCaller creates a new read-only instance of Home, bound to a specific deployed contract. +func NewHomeCaller(address common.Address, caller bind.ContractCaller) (*HomeCaller, error) { + contract, err := bindHome(address, caller, nil, nil) if err != nil { return nil, err } - return &HomeNewUpdaterIterator{contract: _Home.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &HomeCaller{contract: contract}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *HomeNewUpdater) (event.Subscription, error) { +// NewHomeTransactor creates a new write-only instance of Home, bound to a specific deployed contract. +func NewHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*HomeTransactor, error) { + contract, err := bindHome(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &HomeTransactor{contract: contract}, nil +} - logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdater") +// NewHomeFilterer creates a new log filterer instance of Home, bound to a specific deployed contract. +func NewHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*HomeFilterer, error) { + contract, err := bindHome(address, nil, nil, filterer) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeNewUpdater) - if err := _Home.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &HomeFilterer{contract: contract}, nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) ParseNewUpdater(log types.Log) (*HomeNewUpdater, error) { - event := new(HomeNewUpdater) - if err := _Home.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// bindHome binds a generic wrapper to an already deployed contract. +func bindHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HomeABI)) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// HomeNewUpdaterManagerIterator is returned from FilterNewUpdaterManager and is used to iterate over the raw logs and unpacked data for NewUpdaterManager events raised by the Home contract. -type HomeNewUpdaterManagerIterator struct { - Event *HomeNewUpdaterManager // Event containing the contract specifics and raw log +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Home *HomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Home.Contract.HomeCaller.contract.Call(opts, result, method, params...) +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Home *HomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.Contract.HomeTransactor.contract.Transfer(opts) +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Transact invokes the (paid) contract method with params as input values. +func (_Home *HomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Home.Contract.HomeTransactor.contract.Transact(opts, method, params...) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeNewUpdaterManagerIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdaterManager) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Home *HomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Home.Contract.contract.Call(opts, result, method, params...) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdaterManager) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Home *HomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.Contract.contract.Transfer(opts) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transact invokes the (paid) contract method with params as input values. +func (_Home *HomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Home.Contract.contract.Transact(opts, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeNewUpdaterManagerIterator) Error() error { - return it.fail +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeCaller) MAXMESSAGEBODYBYTES(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "MAX_MESSAGE_BODY_BYTES") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeNewUpdaterManagerIterator) Close() error { - it.sub.Unsubscribe() - return nil +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { + return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) } -// HomeNewUpdaterManager represents a NewUpdaterManager event raised by the Home contract. -type HomeNewUpdaterManager struct { - UpdaterManager common.Address - Raw types.Log // Blockchain specific contextual infos +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeCallerSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { + return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) } -// FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) FilterNewUpdaterManager(opts *bind.FilterOpts) (*HomeNewUpdaterManagerIterator, error) { +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeCaller) VERSION(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "VERSION") - logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdaterManager") if err != nil { - return nil, err + return *new(uint8), err } - return &HomeNewUpdaterManagerIterator{contract: _Home.contract, event: "NewUpdaterManager", logs: logs, sub: sub}, nil + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + } -// WatchNewUpdaterManager is a free log subscription operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *HomeNewUpdaterManager) (event.Subscription, error) { +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeSession) VERSION() (uint8, error) { + return _Home.Contract.VERSION(&_Home.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeCallerSession) VERSION() (uint8, error) { + return _Home.Contract.VERSION(&_Home.CallOpts) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "allGuards") - logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdaterManager") if err != nil { - return nil, err + return *new([]common.Address), err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeNewUpdaterManager) - if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + } -// ParseNewUpdaterManager is a log parse operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) ParseNewUpdaterManager(log types.Log) (*HomeNewUpdaterManager, error) { - event := new(HomeNewUpdaterManager) - if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeSession) AllGuards() ([]common.Address, error) { + return _Home.Contract.AllGuards(&_Home.CallOpts) } -// HomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Home contract. -type HomeOwnershipTransferredIterator struct { - Event *HomeOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeCallerSession) AllGuards() ([]common.Address, error) { + return _Home.Contract.AllGuards(&_Home.CallOpts) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeCaller) AllNotaries(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "allNotaries") - default: - return false - } + if err != nil { + return *new([]common.Address), err } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeOwnershipTransferredIterator) Error() error { - return it.fail -} + return out0, err -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil } -// HomeOwnershipTransferred represents a OwnershipTransferred event raised by the Home contract. -type HomeOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeSession) AllNotaries() ([]common.Address, error) { + return _Home.Contract.AllNotaries(&_Home.CallOpts) } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*HomeOwnershipTransferredIterator, error) { +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeCallerSession) AllNotaries() ([]common.Address, error) { + return _Home.Contract.AllNotaries(&_Home.CallOpts) +} - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_Home *HomeCaller) Count(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "count") - logs, sub, err := _Home.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { - return nil, err + return *new(*big.Int), err } - return &HomeOwnershipTransferredIterator{contract: _Home.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// Count is a free data retrieval call binding the contract method 0x06661abd. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *HomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { +// Solidity: function count() view returns(uint256) +func (_Home *HomeSession) Count() (*big.Int, error) { + return _Home.Contract.Count(&_Home.CallOpts) +} - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_Home *HomeCallerSession) Count() (*big.Int, error) { + return _Home.Contract.Count(&_Home.CallOpts) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "getGuard", _index) - logs, sub, err := _Home.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { - return nil, err + return *new(common.Address), err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeOwnershipTransferred) - if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) ParseOwnershipTransferred(log types.Log) (*HomeOwnershipTransferred, error) { - event := new(HomeOwnershipTransferred) - if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeSession) GetGuard(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetGuard(&_Home.CallOpts, _index) } -// HomeUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the Home contract. -type HomeUpdateIterator struct { - Event *HomeUpdate // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetGuard(&_Home.CallOpts, _index) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeUpdateIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeCaller) GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "getNotary", _index) - default: - return false - } + if err != nil { + return *new(common.Address), err } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeUpdateIterator) Error() error { - return it.fail -} + return out0, err -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeUpdateIterator) Close() error { - it.sub.Unsubscribe() - return nil } -// HomeUpdate represents a Update event raised by the Home contract. -type HomeUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeSession) GetNotary(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetNotary(&_Home.CallOpts, _index) } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*HomeUpdateIterator, error) { +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeCallerSession) GetNotary(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetNotary(&_Home.CallOpts, _index) +} - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "guardsAmount") - logs, sub, err := _Home.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new(*big.Int), err } - return &HomeUpdateIterator{contract: _Home.contract, event: "Update", logs: logs, sub: sub}, nil + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *HomeUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeSession) GuardsAmount() (*big.Int, error) { + return _Home.Contract.GuardsAmount(&_Home.CallOpts) +} - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeCallerSession) GuardsAmount() (*big.Int, error) { + return _Home.Contract.GuardsAmount(&_Home.CallOpts) +} + +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "historicalRoots", arg0) - logs, sub, err := _Home.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new([32]byte), err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeUpdate) - if err := _Home.contract.UnpackLog(event, "Update", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) ParseUpdate(log types.Log) (*HomeUpdate, error) { - event := new(HomeUpdate) - if err := _Home.contract.UnpackLog(event, "Update", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) } -// HomeUpdaterSlashedIterator is returned from FilterUpdaterSlashed and is used to iterate over the raw logs and unpacked data for UpdaterSlashed events raised by the Home contract. -type HomeUpdaterSlashedIterator struct { - Event *HomeUpdaterSlashed // Event containing the contract specifics and raw log +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "localDomain") -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeUpdaterSlashedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false + if err != nil { + return *new(uint32), err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeUpdaterSlashed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeUpdaterSlashed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} + return out0, err -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeUpdaterSlashedIterator) Error() error { - return it.fail } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeUpdaterSlashedIterator) Close() error { - it.sub.Unsubscribe() - return nil +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeSession) LocalDomain() (uint32, error) { + return _Home.Contract.LocalDomain(&_Home.CallOpts) } -// HomeUpdaterSlashed represents a UpdaterSlashed event raised by the Home contract. -type HomeUpdaterSlashed struct { - Updater common.Address - Reporter common.Address - Raw types.Log // Blockchain specific contextual infos +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeCallerSession) LocalDomain() (uint32, error) { + return _Home.Contract.LocalDomain(&_Home.CallOpts) } -// FilterUpdaterSlashed is a free log retrieval operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. // -// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) -func (_Home *HomeFilterer) FilterUpdaterSlashed(opts *bind.FilterOpts, updater []common.Address, reporter []common.Address) (*HomeUpdaterSlashedIterator, error) { - - var updaterRule []interface{} - for _, updaterItem := range updater { - updaterRule = append(updaterRule, updaterItem) - } - var reporterRule []interface{} - for _, reporterItem := range reporter { - reporterRule = append(reporterRule, reporterItem) - } +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeCaller) Nonce(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "nonce") - logs, sub, err := _Home.contract.FilterLogs(opts, "UpdaterSlashed", updaterRule, reporterRule) if err != nil { - return nil, err + return *new(uint32), err } - return &HomeUpdaterSlashedIterator{contract: _Home.contract, event: "UpdaterSlashed", logs: logs, sub: sub}, nil + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// WatchUpdaterSlashed is a free log subscription operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. // -// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) -func (_Home *HomeFilterer) WatchUpdaterSlashed(opts *bind.WatchOpts, sink chan<- *HomeUpdaterSlashed, updater []common.Address, reporter []common.Address) (event.Subscription, error) { +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeSession) Nonce() (uint32, error) { + return _Home.Contract.Nonce(&_Home.CallOpts) +} - var updaterRule []interface{} - for _, updaterItem := range updater { - updaterRule = append(updaterRule, updaterItem) - } - var reporterRule []interface{} - for _, reporterItem := range reporter { - reporterRule = append(reporterRule, reporterItem) - } +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeCallerSession) Nonce() (uint32, error) { + return _Home.Contract.Nonce(&_Home.CallOpts) +} + +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeCaller) NotariesAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "notariesAmount") - logs, sub, err := _Home.contract.WatchLogs(opts, "UpdaterSlashed", updaterRule, reporterRule) if err != nil { - return nil, err + return *new(*big.Int), err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeUpdaterSlashed) - if err := _Home.contract.UnpackLog(event, "UpdaterSlashed", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// ParseUpdaterSlashed is a log parse operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. // -// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) -func (_Home *HomeFilterer) ParseUpdaterSlashed(log types.Log) (*HomeUpdaterSlashed, error) { - event := new(HomeUpdaterSlashed) - if err := _Home.contract.UnpackLog(event, "UpdaterSlashed", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeSession) NotariesAmount() (*big.Int, error) { + return _Home.Contract.NotariesAmount(&_Home.CallOpts) } -// HomeHarnessMetaData contains all meta data concerning the HomeHarness contract. -var HomeHarnessMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destination\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"}],\"name\":\"destinationAndNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sensitiveValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"setFailed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newValue\",\"type\":\"uint256\"}],\"name\":\"setSensitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enumHome.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "522ae002": "MAX_MESSAGE_BODY_BYTES()", - "ffa1ad74": "VERSION()", - "06661abd": "count()", - "da180e70": "destinationAndNonce(uint32,uint32)", - "f7560e40": "dispatch(uint32,bytes32,uint32,bytes,bytes)", - "7ea97f40": "historicalRoots(uint256)", - "0afe7f90": "improperAttestation(bytes)", - "c4d66de8": "initialize(address)", - "8d3638f4": "localDomain()", - "affed0e0": "nonce()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "ebf0c717": "root()", - "089d2894": "sensitiveValue()", - "146901db": "setFailed()", - "48639d24": "setSensitiveValue(uint256)", - "b7bc563e": "setSystemMessenger(address)", - "9d54f419": "setUpdater(address)", - "9776120e": "setUpdaterManager(address)", - "c19d93fb": "state()", - "36e104de": "suggestUpdate()", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "fd54b228": "tree()", - "df034cd0": "updater()", - "9df6c8e1": "updaterManager()", - }, - Bin: "0x60a06040523480156200001157600080fd5b50604051620037f0380380620037f0833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b6080516137546200009c600039600081816102d601528181610e8601526118ee01526137546000f3fe6080604052600436106101a15760003560e01c80639df6c8e1116100e1578063da180e701161008a578063f2fde38b11610064578063f2fde38b14610519578063f7560e4014610539578063fd54b2281461054c578063ffa1ad741461056357600080fd5b8063da180e701461049e578063df034cd0146104d7578063ebf0c7171461050457600080fd5b8063c19d93fb116100bb578063c19d93fb1461040d578063c4d66de814610451578063ccbdf9c91461047157600080fd5b80639df6c8e114610399578063affed0e0146103cf578063b7bc563e146103ed57600080fd5b8063522ae0021161014e5780638d3638f4116101285780638d3638f4146102c45780638da5cb5b1461030d5780639776120e146103595780639d54f4191461037957600080fd5b8063522ae00214610279578063715018a61461028f5780637ea97f40146102a457600080fd5b8063146901db1161017f578063146901db1461021157806336e104de1461022857806348639d241461025957600080fd5b806306661abd146101a6578063089d2894146101ca5780630afe7f90146101e1575b600080fd5b3480156101b257600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101d657600080fd5b506101b761014b5481565b3480156101ed57600080fd5b506102016101fc366004612fda565b61058a565b60405190151581526020016101c1565b34801561021d57600080fd5b506102266106e0565b005b34801561023457600080fd5b5061023d6106ea565b6040805163ffffffff90931683526020830191909152016101c1565b34801561026557600080fd5b5061022661027436600461300f565b610731565b34801561028557600080fd5b506101b761080081565b34801561029b57600080fd5b5061022661073f565b3480156102b057600080fd5b506101b76102bf36600461300f565b6107a6565b3480156102d057600080fd5b506102f87f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101c1565b34801561031957600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c1565b34801561036557600080fd5b5061022661037436600461304a565b6107c7565b34801561038557600080fd5b5061022661039436600461304a565b61083a565b3480156103a557600080fd5b5061011b5461033490640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103db57600080fd5b5061011b546102f89063ffffffff1681565b3480156103f957600080fd5b5061022661040836600461304a565b6108fa565b34801561041957600080fd5b5061011b54610444907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101c19190613096565b34801561045d57600080fd5b5061022661046c36600461304a565b6109a8565b34801561047d57600080fd5b5060b8546103349073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104aa57600080fd5b506104be6104b93660046130eb565b610b6a565b60405167ffffffffffffffff90911681526020016101c1565b3480156104e357600080fd5b5060b7546103349073ffffffffffffffffffffffffffffffffffffffff1681565b34801561051057600080fd5b506101b7610b8d565b34801561052557600080fd5b5061022661053436600461304a565b610b9e565b61022661054736600461311e565b610c97565b34801561055857600080fd5b506020546101b79081565b34801561056f57600080fd5b50610578600081565b60405160ff90911681526020016101c1565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff1660028111156105c2576105c2613067565b036106145760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061062084610f91565b9150915060006106358262ffffff19166110a1565b9050600061064862ffffff1984166110b5565b60215490915063ffffffff831610156106915760218263ffffffff1681548110610674576106746131ad565b906000526020600020015481036106915750600095945050505050565b6106996110ca565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106ca929190613256565b60405180910390a160019450505050505b919050565b6106e86110ca565b565b6021546000908190801561072c576107036001826132b4565b925060218363ffffffff168154811061071e5761071e6131ad565b906000526020600020015491505b509091565b6107396111e5565b61014b55565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b602181815481106107b657600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff16331461082e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b6108378161124c565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108aa5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161060b565b6108b381611334565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006109b460016113b3565b905080156109e957605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6109f28261124c565b610a8c61011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8791906132cb565b611507565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610b6657605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b600067ffffffff00000000602084901b1663ffffffff8316175b90505b92915050565b6000610b996000611595565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b73ffffffffffffffffffffffffffffffffffffffff8116610c8e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161060b565b610837816115a8565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610ccd57610ccd613067565b03610d1a5760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161060b565b61080081511115610d6d5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161060b565b34610d85610d7a8461161f565b62ffffff191661162c565b6bffffffffffffffffffffffff1614610de05760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161060b565b61011b54610df59063ffffffff1660016132e8565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e368561168e565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f008286866116ed565b80516020820120909150610f1381611768565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f4260205490565b610f4c91906132b4565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f7e929190613310565b60405180910390a4505050505050505050565b600080610f9e8382611798565b905060286bffffffffffffffffffffffff601883901c16116110025760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161060b565b61103661101462ffffff1983166117bc565b61103161102662ffffff1985166117d1565b62ffffff1916611804565b611857565b915061105061104a62ffffff1983166118d6565b836118ea565b61109c5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161060b565b915091565b6000610b8762ffffff19831660048061198b565b6000610b8762ffffff198316600860206119bb565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b15801561118457600080fd5b505af1158015611198573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106e85760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161060b565b73ffffffffffffffffffffffffffffffffffffffff81163b6112b05760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161060b565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610b5d565b605254600090610100900460ff1615611452578160ff1660011480156113d85750303b155b61144a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161060b565b506000919050565b60525460ff8084169116106114cf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161060b565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115845760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b61158c611b79565b61083781611334565b6000610b87826115a3611bfe565b6120bf565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610b87826002611798565b60008161164260025b62ffffff19831690612182565b5061164c83612283565b611655846122b1565b61165e856122d2565b611667866122f3565b6116719190613335565b61167b9190613335565b6116859190613335565b91505b50919050565b60007fffffffffffffffffffffffff000000000000000000000000000000000000000082146116be573392915050565b6116c66111e5565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906117016004600261335c565b60ff1661170e9190613385565b9050600084518261171f9190613385565b9050600161172f6004600261335c565b60ff16838389898960405160200161174d97969594939291906133a2565b604051602081830303815290604052925050505b9392505050565b611773600082612314565b602161177f6000611595565b8154600181018355600092835260209092209091015550565b8151600090602084016117b364ffffffffff85168284612437565b95945050505050565b6000610b8762ffffff1983168260288161247e565b6000610b8760286117f481601886901c6bffffffffffffffffffffffff166132b4565b62ffffff1985169190600061247e565b60606000806118218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506118468483602001612502565b508181016020016040529052919050565b60008061186962ffffff19851661269d565b90506118c2816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506118ce81846126fa565b949350505050565b6000610b8762ffffff19831682600461198b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119675760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161060b565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b6000611998826020613440565b6119a390600861335c565b60ff166119b18585856119bb565b901c949350505050565b60008160ff166000036119d057506000611761565b6119e88460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611a0360ff841685613463565b1115611a7b57611a62611a248560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611a4a8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661271e565b60405162461bcd60e51b815260040161060b919061347b565b60208260ff161115611af55760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161060b565b600882026000611b138660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611bf65760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b6106e861278c565b611c06612ee1565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561217a57600182821c811690819003612126578582602081106120f3576120f36131ad565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612171565b83858360208110612139576121396131ad565b6020020151604051602001612158929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016120c9565b505092915050565b600061218e8383612812565b61227c5760006121ad6121a18560d81c90565b64ffffffffff16612835565b91505060006121c28464ffffffffff16612835565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161060b919061347b565b5090919050565b6000816122906002611635565b506122a462ffffff1984166026600c61198b565b63ffffffff169392505050565b6000816122be6002611635565b506122a462ffffff198416601a600c61198b565b6000816122df6002611635565b506122a462ffffff198416600e600c61198b565b6000816123006002611635565b506122a462ffffff1984166002600c61198b565b602080830154906001906123299060026135a6565b61233391906132b4565b81106123815760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161060b565b6001016020830181905560005b602081101561242957816001166001036123bd57828482602081106123b5576123b56131ad565b015550505050565b8381602081106123cf576123cf6131ad565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161238e565b506124326135b2565b505050565b6000806124448385613463565b9050604051811115612454575060005b806000036124695762ffffff19915050611761565b5050606092831b9190911790911b1760181b90565b6000806124998660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506124b28661291f565b846124bd8784613463565b6124c79190613463565b11156124da5762ffffff199150506118ce565b6124e48582613463565b90506124f88364ffffffffff168286612437565b9695505050505050565b600062ffffff198084160361257f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161060b565b61258883612967565b6125fa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161060b565b60006126148460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061263e8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156126635760206060fd5b8285848460045afa506124f86126798760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806126b88360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126e28460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061270985856129a4565b9150915061271681612a12565b509392505050565b6060600061272b86612835565b915050600061273986612835565b915050600061274786612835565b915050600061275586612835565b9150508383838360405160200161276f94939291906135e1565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166128095760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b6106e8336115a8565b60008164ffffffffff166128268460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156128a857600061285482600861335c565b60ff1685901c905061286581612bfe565b61ffff16841793508160ff1660101461288057601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161283b565b50600f5b60ff8160ff1610156129195760006128c582600861335c565b60ff1685901c90506128d681612bfe565b61ffff16831792508160ff166000146128f157601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128ac565b50915091565b60006129398260181c6bffffffffffffffffffffffff1690565b6129518360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006129738260d81c90565b64ffffffffff1664ffffffffff0361298d57506000919050565b60006129988361291f565b60405110199392505050565b60008082516041036129da5760208301516040840151606085015160001a6129ce87828585612c30565b94509450505050612a0b565b8251604003612a0357602083015160408401516129f8868383612d48565b935093505050612a0b565b506000905060025b9250929050565b6000816004811115612a2657612a26613067565b03612a2e5750565b6001816004811115612a4257612a42613067565b03612a8f5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161060b565b6002816004811115612aa357612aa3613067565b03612af05760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161060b565b6003816004811115612b0457612b04613067565b03612b775760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161060b565b6004816004811115612b8b57612b8b613067565b036108375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161060b565b6000612c1060048360ff16901c612d9a565b60ff1661ffff919091161760081b612c2782612d9a565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c675750600090506003612d3f565b8460ff16601b14158015612c7f57508460ff16601c14155b15612c905750600090506004612d3f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612ce4573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612d3857600060019250925050612d3f565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612d7e60ff86901c601b613463565b9050612d8c87828885612c30565b935093505050935093915050565b600060f08083179060ff82169003612db55750603092915050565b8060ff1660f103612dc95750603192915050565b8060ff1660f203612ddd5750603292915050565b8060ff1660f303612df15750603392915050565b8060ff1660f403612e055750603492915050565b8060ff1660f503612e195750603592915050565b8060ff1660f603612e2d5750603692915050565b8060ff1660f703612e415750603792915050565b8060ff1660f803612e555750603892915050565b8060ff1660f903612e695750603992915050565b8060ff1660fa03612e7d5750606192915050565b8060ff1660fb03612e915750606292915050565b8060ff1660fc03612ea55750606392915050565b8060ff1660fd03612eb95750606492915050565b8060ff1660fe03612ecd5750606592915050565b8060ff1660ff036116885750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612f4057600080fd5b813567ffffffffffffffff80821115612f5b57612f5b612f00565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612fa157612fa1612f00565b81604052838152866020858801011115612fba57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612fec57600080fd5b813567ffffffffffffffff81111561300357600080fd5b6118ce84828501612f2f565b60006020828403121561302157600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461083757600080fd5b60006020828403121561305c57600080fd5b813561176181613028565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106130d1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106db57600080fd5b600080604083850312156130fe57600080fd5b613107836130d7565b9150613115602084016130d7565b90509250929050565b600080600080600060a0868803121561313657600080fd5b61313f866130d7565b945060208601359350613154604087016130d7565b9250606086013567ffffffffffffffff8082111561317157600080fd5b61317d89838a01612f2f565b9350608088013591508082111561319357600080fd5b506131a088828901612f2f565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156131f75781810151838201526020016131df565b83811115613206576000848401525b50505050565b600081518084526132248160208601602086016131dc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006118ce604083018461320c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156132c6576132c6613285565b500390565b6000602082840312156132dd57600080fd5b815161176181613028565b600063ffffffff80831681851680830382111561330757613307613285565b01949350505050565b604081526000613323604083018561320c565b82810360208401526117b3818561320c565b60006bffffffffffffffffffffffff80831681851680830382111561330757613307613285565b600060ff821660ff84168160ff048111821515161561337d5761337d613285565b029392505050565b600061ffff80831681851680830382111561330757613307613285565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134028160088501602089016131dc565b8451908301906134198160088401602089016131dc565b845191019061342f8160088401602088016131dc565b016008019998505050505050505050565b600060ff821660ff84168082101561345a5761345a613285565b90039392505050565b6000821982111561347657613476613285565b500190565b602081526000610b84602083018461320c565b600181815b808511156134e757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156134cd576134cd613285565b808516156134da57918102915b93841c9390800290613493565b509250929050565b6000826134fe57506001610b87565b8161350b57506000610b87565b8160018114613521576002811461352b57613547565b6001915050610b87565b60ff84111561353c5761353c613285565b50506001821b610b87565b5060208310610133831016604e8410600b841016171561356a575081810a610b87565b613574838361348e565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561337d5761337d613285565b6000610b8483836134ef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016124f856fea264697066735822122037ab8d40eb39e867f1417038e0c4eb81544094d7cb53a67fa3b48171a87ae08064736f6c634300080d0033", +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeCallerSession) NotariesAmount() (*big.Int, error) { + return _Home.Contract.NotariesAmount(&_Home.CallOpts) } -// HomeHarnessABI is the input ABI used to generate the binding from. -// Deprecated: Use HomeHarnessMetaData.ABI instead. -var HomeHarnessABI = HomeHarnessMetaData.ABI - -// Deprecated: Use HomeHarnessMetaData.Sigs instead. -// HomeHarnessFuncSigs maps the 4-byte function signature to its string representation. -var HomeHarnessFuncSigs = HomeHarnessMetaData.Sigs - -// HomeHarnessBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HomeHarnessMetaData.Bin instead. -var HomeHarnessBin = HomeHarnessMetaData.Bin +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "owner") -// DeployHomeHarness deploys a new Ethereum contract, binding an instance of HomeHarness to it. -func DeployHomeHarness(auth *bind.TransactOpts, backend bind.ContractBackend, _domain uint32) (common.Address, *types.Transaction, *HomeHarness, error) { - parsed, err := HomeHarnessMetaData.GetAbi() if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + return *new(common.Address), err } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HomeHarnessBin), backend, _domain) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &HomeHarness{HomeHarnessCaller: HomeHarnessCaller{contract: contract}, HomeHarnessTransactor: HomeHarnessTransactor{contract: contract}, HomeHarnessFilterer: HomeHarnessFilterer{contract: contract}}, nil -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err -// HomeHarness is an auto generated Go binding around an Ethereum contract. -type HomeHarness struct { - HomeHarnessCaller // Read-only binding to the contract - HomeHarnessTransactor // Write-only binding to the contract - HomeHarnessFilterer // Log filterer for contract events } -// HomeHarnessCaller is an auto generated read-only Go binding around an Ethereum contract. -type HomeHarnessCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeSession) Owner() (common.Address, error) { + return _Home.Contract.Owner(&_Home.CallOpts) } -// HomeHarnessTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HomeHarnessTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeCallerSession) Owner() (common.Address, error) { + return _Home.Contract.Owner(&_Home.CallOpts) } -// HomeHarnessFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HomeHarnessFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// HomeHarnessSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type HomeHarnessSession struct { - Contract *HomeHarness // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// HomeHarnessCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type HomeHarnessCallerSession struct { - Contract *HomeHarnessCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// HomeHarnessTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type HomeHarnessTransactorSession struct { - Contract *HomeHarnessTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeCaller) Root(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "root") -// HomeHarnessRaw is an auto generated low-level Go binding around an Ethereum contract. -type HomeHarnessRaw struct { - Contract *HomeHarness // Generic contract binding to access the raw methods on -} + if err != nil { + return *new([32]byte), err + } -// HomeHarnessCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HomeHarnessCallerRaw struct { - Contract *HomeHarnessCaller // Generic read-only contract binding to access the raw methods on -} + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) -// HomeHarnessTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HomeHarnessTransactorRaw struct { - Contract *HomeHarnessTransactor // Generic write-only contract binding to access the raw methods on -} + return out0, err -// NewHomeHarness creates a new instance of HomeHarness, bound to a specific deployed contract. -func NewHomeHarness(address common.Address, backend bind.ContractBackend) (*HomeHarness, error) { - contract, err := bindHomeHarness(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &HomeHarness{HomeHarnessCaller: HomeHarnessCaller{contract: contract}, HomeHarnessTransactor: HomeHarnessTransactor{contract: contract}, HomeHarnessFilterer: HomeHarnessFilterer{contract: contract}}, nil } -// NewHomeHarnessCaller creates a new read-only instance of HomeHarness, bound to a specific deployed contract. -func NewHomeHarnessCaller(address common.Address, caller bind.ContractCaller) (*HomeHarnessCaller, error) { - contract, err := bindHomeHarness(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &HomeHarnessCaller{contract: contract}, nil +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeSession) Root() ([32]byte, error) { + return _Home.Contract.Root(&_Home.CallOpts) } -// NewHomeHarnessTransactor creates a new write-only instance of HomeHarness, bound to a specific deployed contract. -func NewHomeHarnessTransactor(address common.Address, transactor bind.ContractTransactor) (*HomeHarnessTransactor, error) { - contract, err := bindHomeHarness(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &HomeHarnessTransactor{contract: contract}, nil +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeCallerSession) Root() ([32]byte, error) { + return _Home.Contract.Root(&_Home.CallOpts) } -// NewHomeHarnessFilterer creates a new log filterer instance of HomeHarness, bound to a specific deployed contract. -func NewHomeHarnessFilterer(address common.Address, filterer bind.ContractFilterer) (*HomeHarnessFilterer, error) { - contract, err := bindHomeHarness(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &HomeHarnessFilterer{contract: contract}, nil -} +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeCaller) State(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "state") -// bindHomeHarness binds a generic wrapper to an already deployed contract. -func bindHomeHarness(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HomeHarnessABI)) if err != nil { - return nil, err + return *new(uint8), err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_HomeHarness *HomeHarnessRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _HomeHarness.Contract.HomeHarnessCaller.contract.Call(opts, result, method, params...) -} -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_HomeHarness *HomeHarnessRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _HomeHarness.Contract.HomeHarnessTransactor.contract.Transfer(opts) -} + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) -// Transact invokes the (paid) contract method with params as input values. -func (_HomeHarness *HomeHarnessRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _HomeHarness.Contract.HomeHarnessTransactor.contract.Transact(opts, method, params...) -} + return out0, err -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_HomeHarness *HomeHarnessCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _HomeHarness.Contract.contract.Call(opts, result, method, params...) } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_HomeHarness *HomeHarnessTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _HomeHarness.Contract.contract.Transfer(opts) +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeSession) State() (uint8, error) { + return _Home.Contract.State(&_Home.CallOpts) } -// Transact invokes the (paid) contract method with params as input values. -func (_HomeHarness *HomeHarnessTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _HomeHarness.Contract.contract.Transact(opts, method, params...) +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeCallerSession) State() (uint8, error) { + return _Home.Contract.State(&_Home.CallOpts) } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. // -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_HomeHarness *HomeHarnessCaller) MAXMESSAGEBODYBYTES(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeCaller) SuggestUpdate(opts *bind.CallOpts) (struct { + Nonce uint32 + Root [32]byte +}, error) { var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "MAX_MESSAGE_BODY_BYTES") + err := _Home.contract.Call(opts, &out, "suggestUpdate") + outstruct := new(struct { + Nonce uint32 + Root [32]byte + }) if err != nil { - return *new(*big.Int), err + return *outstruct, err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Nonce = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) - return out0, err + return *outstruct, err } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. // -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_HomeHarness *HomeHarnessSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { - return _HomeHarness.Contract.MAXMESSAGEBODYBYTES(&_HomeHarness.CallOpts) +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeSession) SuggestUpdate() (struct { + Nonce uint32 + Root [32]byte +}, error) { + return _Home.Contract.SuggestUpdate(&_Home.CallOpts) } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. // -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_HomeHarness *HomeHarnessCallerSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { - return _HomeHarness.Contract.MAXMESSAGEBODYBYTES(&_HomeHarness.CallOpts) +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeCallerSession) SuggestUpdate() (struct { + Nonce uint32 + Root [32]byte +}, error) { + return _Home.Contract.SuggestUpdate(&_Home.CallOpts) } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. // -// Solidity: function VERSION() view returns(uint8) -func (_HomeHarness *HomeHarnessCaller) VERSION(opts *bind.CallOpts) (uint8, error) { +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "VERSION") + err := _Home.contract.Call(opts, &out, "systemMessenger") if err != nil { - return *new(uint8), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. // -// Solidity: function VERSION() view returns(uint8) -func (_HomeHarness *HomeHarnessSession) VERSION() (uint8, error) { - return _HomeHarness.Contract.VERSION(&_HomeHarness.CallOpts) +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeSession) SystemMessenger() (common.Address, error) { + return _Home.Contract.SystemMessenger(&_Home.CallOpts) } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. // -// Solidity: function VERSION() view returns(uint8) -func (_HomeHarness *HomeHarnessCallerSession) VERSION() (uint8, error) { - return _HomeHarness.Contract.VERSION(&_HomeHarness.CallOpts) +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeCallerSession) SystemMessenger() (common.Address, error) { + return _Home.Contract.SystemMessenger(&_Home.CallOpts) } -// Count is a free data retrieval call binding the contract method 0x06661abd. +// Tree is a free data retrieval call binding the contract method 0xfd54b228. // -// Solidity: function count() view returns(uint256) -func (_HomeHarness *HomeHarnessCaller) Count(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "count") + err := _Home.contract.Call(opts, &out, "tree") if err != nil { return *new(*big.Int), err @@ -3774,650 +3676,3046 @@ func (_HomeHarness *HomeHarnessCaller) Count(opts *bind.CallOpts) (*big.Int, err } -// Count is a free data retrieval call binding the contract method 0x06661abd. +// Tree is a free data retrieval call binding the contract method 0xfd54b228. // -// Solidity: function count() view returns(uint256) -func (_HomeHarness *HomeHarnessSession) Count() (*big.Int, error) { - return _HomeHarness.Contract.Count(&_HomeHarness.CallOpts) +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeSession) Tree() (*big.Int, error) { + return _Home.Contract.Tree(&_Home.CallOpts) } -// Count is a free data retrieval call binding the contract method 0x06661abd. +// Tree is a free data retrieval call binding the contract method 0xfd54b228. // -// Solidity: function count() view returns(uint256) -func (_HomeHarness *HomeHarnessCallerSession) Count() (*big.Int, error) { - return _HomeHarness.Contract.Count(&_HomeHarness.CallOpts) +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeCallerSession) Tree() (*big.Int, error) { + return _Home.Contract.Tree(&_Home.CallOpts) } -// DestinationAndNonce is a free data retrieval call binding the contract method 0xda180e70. +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. // -// Solidity: function destinationAndNonce(uint32 _destination, uint32 _nonce) pure returns(uint64) -func (_HomeHarness *HomeHarnessCaller) DestinationAndNonce(opts *bind.CallOpts, _destination uint32, _nonce uint32) (uint64, error) { +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeCaller) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "destinationAndNonce", _destination, _nonce) + err := _Home.contract.Call(opts, &out, "updaterManager") if err != nil { - return *new(uint64), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// DestinationAndNonce is a free data retrieval call binding the contract method 0xda180e70. +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. // -// Solidity: function destinationAndNonce(uint32 _destination, uint32 _nonce) pure returns(uint64) -func (_HomeHarness *HomeHarnessSession) DestinationAndNonce(_destination uint32, _nonce uint32) (uint64, error) { - return _HomeHarness.Contract.DestinationAndNonce(&_HomeHarness.CallOpts, _destination, _nonce) -} +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeSession) UpdaterManager() (common.Address, error) { + return _Home.Contract.UpdaterManager(&_Home.CallOpts) +} -// DestinationAndNonce is a free data retrieval call binding the contract method 0xda180e70. +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. // -// Solidity: function destinationAndNonce(uint32 _destination, uint32 _nonce) pure returns(uint64) -func (_HomeHarness *HomeHarnessCallerSession) DestinationAndNonce(_destination uint32, _nonce uint32) (uint64, error) { - return _HomeHarness.Contract.DestinationAndNonce(&_HomeHarness.CallOpts, _destination, _nonce) +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeCallerSession) UpdaterManager() (common.Address, error) { + return _Home.Contract.UpdaterManager(&_Home.CallOpts) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. // -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_HomeHarness *HomeHarnessCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "historicalRoots", arg0) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeTransactor) Dispatch(opts *bind.TransactOpts, _destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "dispatch", _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. // -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_HomeHarness *HomeHarnessSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _HomeHarness.Contract.HistoricalRoots(&_HomeHarness.CallOpts, arg0) +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. // -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_HomeHarness *HomeHarnessCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _HomeHarness.Contract.HistoricalRoots(&_HomeHarness.CallOpts, arg0) +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeTransactorSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. // -// Solidity: function localDomain() view returns(uint32) -func (_HomeHarness *HomeHarnessCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "localDomain") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeTransactor) ImproperAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "improperAttestation", _attestation) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. // -// Solidity: function localDomain() view returns(uint32) -func (_HomeHarness *HomeHarnessSession) LocalDomain() (uint32, error) { - return _HomeHarness.Contract.LocalDomain(&_HomeHarness.CallOpts) +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { + return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. // -// Solidity: function localDomain() view returns(uint32) -func (_HomeHarness *HomeHarnessCallerSession) LocalDomain() (uint32, error) { - return _HomeHarness.Contract.LocalDomain(&_HomeHarness.CallOpts) +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeTransactorSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { + return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function nonce() view returns(uint32) -func (_HomeHarness *HomeHarnessCaller) Nonce(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "nonce") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeTransactor) Initialize(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "initialize", _updaterManager) } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function nonce() view returns(uint32) -func (_HomeHarness *HomeHarnessSession) Nonce() (uint32, error) { - return _HomeHarness.Contract.Nonce(&_HomeHarness.CallOpts) +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function nonce() view returns(uint32) -func (_HomeHarness *HomeHarnessCallerSession) Nonce() (uint32, error) { - return _HomeHarness.Contract.Nonce(&_HomeHarness.CallOpts) +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeTransactorSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function owner() view returns(address) -func (_HomeHarness *HomeHarnessCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +// Solidity: function renounceOwnership() returns() +func (_Home *HomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "renounceOwnership") } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function owner() view returns(address) -func (_HomeHarness *HomeHarnessSession) Owner() (common.Address, error) { - return _HomeHarness.Contract.Owner(&_HomeHarness.CallOpts) +// Solidity: function renounceOwnership() returns() +func (_Home *HomeSession) RenounceOwnership() (*types.Transaction, error) { + return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function owner() view returns(address) -func (_HomeHarness *HomeHarnessCallerSession) Owner() (common.Address, error) { - return _HomeHarness.Contract.Owner(&_HomeHarness.CallOpts) +// Solidity: function renounceOwnership() returns() +func (_Home *HomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) } -// Root is a free data retrieval call binding the contract method 0xebf0c717. +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. // -// Solidity: function root() view returns(bytes32) -func (_HomeHarness *HomeHarnessCaller) Root(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "root") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setSystemMessenger", _systemMessenger) } -// Root is a free data retrieval call binding the contract method 0xebf0c717. +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. // -// Solidity: function root() view returns(bytes32) -func (_HomeHarness *HomeHarnessSession) Root() ([32]byte, error) { - return _HomeHarness.Contract.Root(&_HomeHarness.CallOpts) +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) } -// Root is a free data retrieval call binding the contract method 0xebf0c717. +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. // -// Solidity: function root() view returns(bytes32) -func (_HomeHarness *HomeHarnessCallerSession) Root() ([32]byte, error) { - return _HomeHarness.Contract.Root(&_HomeHarness.CallOpts) +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) } -// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. // -// Solidity: function sensitiveValue() view returns(uint256) -func (_HomeHarness *HomeHarnessCaller) SensitiveValue(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "sensitiveValue") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setUpdater", _updater) } -// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. // -// Solidity: function sensitiveValue() view returns(uint256) -func (_HomeHarness *HomeHarnessSession) SensitiveValue() (*big.Int, error) { - return _HomeHarness.Contract.SensitiveValue(&_HomeHarness.CallOpts) +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) } -// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. // -// Solidity: function sensitiveValue() view returns(uint256) -func (_HomeHarness *HomeHarnessCallerSession) SensitiveValue() (*big.Int, error) { - return _HomeHarness.Contract.SensitiveValue(&_HomeHarness.CallOpts) +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. // -// Solidity: function state() view returns(uint8) -func (_HomeHarness *HomeHarnessCaller) State(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "state") - - if err != nil { - return *new(uint8), err - } - - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) - - return out0, err - +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeTransactor) SetUpdaterManager(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setUpdaterManager", _updaterManager) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. // -// Solidity: function state() view returns(uint8) -func (_HomeHarness *HomeHarnessSession) State() (uint8, error) { - return _HomeHarness.Contract.State(&_HomeHarness.CallOpts) +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. // -// Solidity: function state() view returns(uint8) -func (_HomeHarness *HomeHarnessCallerSession) State() (uint8, error) { - return _HomeHarness.Contract.State(&_HomeHarness.CallOpts) +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeTransactorSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_HomeHarness *HomeHarnessCaller) SuggestUpdate(opts *bind.CallOpts) (struct { - Nonce uint32 - Root [32]byte -}, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "suggestUpdate") - - outstruct := new(struct { - Nonce uint32 - Root [32]byte - }) - if err != nil { - return *outstruct, err - } - - outstruct.Nonce = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) - - return *outstruct, err - +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "transferOwnership", newOwner) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_HomeHarness *HomeHarnessSession) SuggestUpdate() (struct { - Nonce uint32 - Root [32]byte -}, error) { - return _HomeHarness.Contract.SuggestUpdate(&_HomeHarness.CallOpts) +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_HomeHarness *HomeHarnessCallerSession) SuggestUpdate() (struct { - Nonce uint32 - Root [32]byte -}, error) { - return _HomeHarness.Contract.SuggestUpdate(&_HomeHarness.CallOpts) +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_HomeHarness *HomeHarnessCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "systemMessenger") +// HomeDispatchIterator is returned from FilterDispatch and is used to iterate over the raw logs and unpacked data for Dispatch events raised by the Home contract. +type HomeDispatchIterator struct { + Event *HomeDispatch // Event containing the contract specifics and raw log - if err != nil { - return *new(common.Address), err + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeDispatchIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeDispatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeDispatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - return out0, err + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeDispatchIterator) Error() error { + return it.fail } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_HomeHarness *HomeHarnessSession) SystemMessenger() (common.Address, error) { - return _HomeHarness.Contract.SystemMessenger(&_HomeHarness.CallOpts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeDispatchIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_HomeHarness *HomeHarnessCallerSession) SystemMessenger() (common.Address, error) { - return _HomeHarness.Contract.SystemMessenger(&_HomeHarness.CallOpts) +// HomeDispatch represents a Dispatch event raised by the Home contract. +type HomeDispatch struct { + MessageHash [32]byte + LeafIndex *big.Int + DestinationAndNonce uint64 + Tips []byte + Message []byte + Raw types.Log // Blockchain specific contextual infos } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// FilterDispatch is a free log retrieval operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. // -// Solidity: function tree() view returns(uint256 count) -func (_HomeHarness *HomeHarnessCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "tree") +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (*HomeDispatchIterator, error) { - if err != nil { - return *new(*big.Int), err + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) + } + var leafIndexRule []interface{} + for _, leafIndexItem := range leafIndex { + leafIndexRule = append(leafIndexRule, leafIndexItem) + } + var destinationAndNonceRule []interface{} + for _, destinationAndNonceItem := range destinationAndNonce { + destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -// Tree is a free data retrieval call binding the contract method 0xfd54b228. -// -// Solidity: function tree() view returns(uint256 count) -func (_HomeHarness *HomeHarnessSession) Tree() (*big.Int, error) { - return _HomeHarness.Contract.Tree(&_HomeHarness.CallOpts) + logs, sub, err := _Home.contract.FilterLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + if err != nil { + return nil, err + } + return &HomeDispatchIterator{contract: _Home.contract, event: "Dispatch", logs: logs, sub: sub}, nil } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// WatchDispatch is a free log subscription operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. // -// Solidity: function tree() view returns(uint256 count) -func (_HomeHarness *HomeHarnessCallerSession) Tree() (*big.Int, error) { - return _HomeHarness.Contract.Tree(&_HomeHarness.CallOpts) -} +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *HomeDispatch, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (event.Subscription, error) { -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_HomeHarness *HomeHarnessCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "updater") + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) + } + var leafIndexRule []interface{} + for _, leafIndexItem := range leafIndex { + leafIndexRule = append(leafIndexRule, leafIndexItem) + } + var destinationAndNonceRule []interface{} + for _, destinationAndNonceItem := range destinationAndNonce { + destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) + } + logs, sub, err := _Home.contract.WatchLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) if err != nil { - return *new(common.Address), err + return nil, err } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeDispatch) + if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + return err + } + event.Raw = log - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_HomeHarness *HomeHarnessSession) Updater() (common.Address, error) { - return _HomeHarness.Contract.Updater(&_HomeHarness.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_HomeHarness *HomeHarnessCallerSession) Updater() (common.Address, error) { - return _HomeHarness.Contract.Updater(&_HomeHarness.CallOpts) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// ParseDispatch is a log parse operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. // -// Solidity: function updaterManager() view returns(address) -func (_HomeHarness *HomeHarnessCaller) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _HomeHarness.contract.Call(opts, &out, "updaterManager") - - if err != nil { - return *new(common.Address), err +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) ParseDispatch(log types.Log) (*HomeDispatch, error) { + event := new(HomeDispatch) + if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + return nil, err } + event.Raw = log + return event, nil +} - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) +// HomeDomainNotaryAddedIterator is returned from FilterDomainNotaryAdded and is used to iterate over the raw logs and unpacked data for DomainNotaryAdded events raised by the Home contract. +type HomeDomainNotaryAddedIterator struct { + Event *HomeDomainNotaryAdded // Event containing the contract specifics and raw log - return out0, err + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. -// -// Solidity: function updaterManager() view returns(address) -func (_HomeHarness *HomeHarnessSession) UpdaterManager() (common.Address, error) { - return _HomeHarness.Contract.UpdaterManager(&_HomeHarness.CallOpts) -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeDomainNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. -// -// Solidity: function updaterManager() view returns(address) -func (_HomeHarness *HomeHarnessCallerSession) UpdaterManager() (common.Address, error) { - return _HomeHarness.Contract.UpdaterManager(&_HomeHarness.CallOpts) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_HomeHarness *HomeHarnessTransactor) Dispatch(opts *bind.TransactOpts, _destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "dispatch", _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_HomeHarness *HomeHarnessSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _HomeHarness.Contract.Dispatch(&_HomeHarness.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeDomainNotaryAddedIterator) Error() error { + return it.fail } -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_HomeHarness *HomeHarnessTransactorSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _HomeHarness.Contract.Dispatch(&_HomeHarness.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeDomainNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_HomeHarness *HomeHarnessTransactor) ImproperAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "improperAttestation", _attestation) +// HomeDomainNotaryAdded represents a DomainNotaryAdded event raised by the Home contract. +type HomeDomainNotaryAdded struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// FilterDomainNotaryAdded is a free log retrieval operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. // -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_HomeHarness *HomeHarnessSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { - return _HomeHarness.Contract.ImproperAttestation(&_HomeHarness.TransactOpts, _attestation) -} +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) FilterDomainNotaryAdded(opts *bind.FilterOpts) (*HomeDomainNotaryAddedIterator, error) { -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_HomeHarness *HomeHarnessTransactorSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { - return _HomeHarness.Contract.ImproperAttestation(&_HomeHarness.TransactOpts, _attestation) + logs, sub, err := _Home.contract.FilterLogs(opts, "DomainNotaryAdded") + if err != nil { + return nil, err + } + return &HomeDomainNotaryAddedIterator{contract: _Home.contract, event: "DomainNotaryAdded", logs: logs, sub: sub}, nil } -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// WatchDomainNotaryAdded is a free log subscription operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. // -// Solidity: function initialize(address _updaterManager) returns() -func (_HomeHarness *HomeHarnessTransactor) Initialize(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "initialize", _updaterManager) -} +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *HomeDomainNotaryAdded) (event.Subscription, error) { -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_HomeHarness *HomeHarnessSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.Initialize(&_HomeHarness.TransactOpts, _updaterManager) -} + logs, sub, err := _Home.contract.WatchLogs(opts, "DomainNotaryAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeDomainNotaryAdded) + if err := _Home.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return err + } + event.Raw = log -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_HomeHarness *HomeHarnessTransactorSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.Initialize(&_HomeHarness.TransactOpts, _updaterManager) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// ParseDomainNotaryAdded is a log parse operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. // -// Solidity: function renounceOwnership() returns() -func (_HomeHarness *HomeHarnessTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "renounceOwnership") +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) ParseDomainNotaryAdded(log types.Log) (*HomeDomainNotaryAdded, error) { + event := new(HomeDomainNotaryAdded) + if err := _Home.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_HomeHarness *HomeHarnessSession) RenounceOwnership() (*types.Transaction, error) { - return _HomeHarness.Contract.RenounceOwnership(&_HomeHarness.TransactOpts) -} +// HomeDomainNotaryRemovedIterator is returned from FilterDomainNotaryRemoved and is used to iterate over the raw logs and unpacked data for DomainNotaryRemoved events raised by the Home contract. +type HomeDomainNotaryRemovedIterator struct { + Event *HomeDomainNotaryRemoved // Event containing the contract specifics and raw log -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_HomeHarness *HomeHarnessTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _HomeHarness.Contract.RenounceOwnership(&_HomeHarness.TransactOpts) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// SetFailed is a paid mutator transaction binding the contract method 0x146901db. -// -// Solidity: function setFailed() returns() -func (_HomeHarness *HomeHarnessTransactor) SetFailed(opts *bind.TransactOpts) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "setFailed") + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// SetFailed is a paid mutator transaction binding the contract method 0x146901db. -// -// Solidity: function setFailed() returns() -func (_HomeHarness *HomeHarnessSession) SetFailed() (*types.Transaction, error) { - return _HomeHarness.Contract.SetFailed(&_HomeHarness.TransactOpts) -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeDomainNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// SetFailed is a paid mutator transaction binding the contract method 0x146901db. -// -// Solidity: function setFailed() returns() -func (_HomeHarness *HomeHarnessTransactorSession) SetFailed() (*types.Transaction, error) { - return _HomeHarness.Contract.SetFailed(&_HomeHarness.TransactOpts) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. -// -// Solidity: function setSensitiveValue(uint256 _newValue) returns() -func (_HomeHarness *HomeHarnessTransactor) SetSensitiveValue(opts *bind.TransactOpts, _newValue *big.Int) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "setSensitiveValue", _newValue) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. -// -// Solidity: function setSensitiveValue(uint256 _newValue) returns() -func (_HomeHarness *HomeHarnessSession) SetSensitiveValue(_newValue *big.Int) (*types.Transaction, error) { - return _HomeHarness.Contract.SetSensitiveValue(&_HomeHarness.TransactOpts, _newValue) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeDomainNotaryRemovedIterator) Error() error { + return it.fail } -// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. -// -// Solidity: function setSensitiveValue(uint256 _newValue) returns() -func (_HomeHarness *HomeHarnessTransactorSession) SetSensitiveValue(_newValue *big.Int) (*types.Transaction, error) { - return _HomeHarness.Contract.SetSensitiveValue(&_HomeHarness.TransactOpts, _newValue) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeDomainNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_HomeHarness *HomeHarnessTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +// HomeDomainNotaryRemoved represents a DomainNotaryRemoved event raised by the Home contract. +type HomeDomainNotaryRemoved struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// FilterDomainNotaryRemoved is a free log retrieval operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. // -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_HomeHarness *HomeHarnessSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.SetSystemMessenger(&_HomeHarness.TransactOpts, _systemMessenger) -} +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*HomeDomainNotaryRemovedIterator, error) { -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_HomeHarness *HomeHarnessTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.SetSystemMessenger(&_HomeHarness.TransactOpts, _systemMessenger) + logs, sub, err := _Home.contract.FilterLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return &HomeDomainNotaryRemovedIterator{contract: _Home.contract, event: "DomainNotaryRemoved", logs: logs, sub: sub}, nil } -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// WatchDomainNotaryRemoved is a free log subscription operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. // -// Solidity: function setUpdater(address _updater) returns() -func (_HomeHarness *HomeHarnessTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "setUpdater", _updater) -} +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *HomeDomainNotaryRemoved) (event.Subscription, error) { -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_HomeHarness *HomeHarnessSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.SetUpdater(&_HomeHarness.TransactOpts, _updater) -} + logs, sub, err := _Home.contract.WatchLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeDomainNotaryRemoved) + if err := _Home.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return err + } + event.Raw = log -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDomainNotaryRemoved is a log parse operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. // -// Solidity: function setUpdater(address _updater) returns() -func (_HomeHarness *HomeHarnessTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.SetUpdater(&_HomeHarness.TransactOpts, _updater) +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) ParseDomainNotaryRemoved(log types.Log) (*HomeDomainNotaryRemoved, error) { + event := new(HomeDomainNotaryRemoved) + if err := _Home.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// HomeGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the Home contract. +type HomeGuardAddedIterator struct { + Event *HomeGuardAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeGuardAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeGuardAdded represents a GuardAdded event raised by the Home contract. +type HomeGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_HomeHarness *HomeHarnessTransactor) SetUpdaterManager(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "setUpdaterManager", _updaterManager) +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*HomeGuardAddedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return &HomeGuardAddedIterator{contract: _Home.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_HomeHarness *HomeHarnessSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.SetUpdaterManager(&_HomeHarness.TransactOpts, _updaterManager) +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *HomeGuardAdded) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeGuardAdded) + if err := _Home.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_HomeHarness *HomeHarnessTransactorSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.SetUpdaterManager(&_HomeHarness.TransactOpts, _updaterManager) +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) ParseGuardAdded(log types.Log) (*HomeGuardAdded, error) { + event := new(HomeGuardAdded) + if err := _Home.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// HomeGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the Home contract. +type HomeGuardRemovedIterator struct { + Event *HomeGuardRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeGuardRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeGuardRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeGuardRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeGuardRemoved represents a GuardRemoved event raised by the Home contract. +type HomeGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_HomeHarness *HomeHarnessTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _HomeHarness.contract.Transact(opts, "transferOwnership", newOwner) +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*HomeGuardRemovedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return &HomeGuardRemovedIterator{contract: _Home.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_HomeHarness *HomeHarnessSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.TransferOwnership(&_HomeHarness.TransactOpts, newOwner) +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *HomeGuardRemoved) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeGuardRemoved) + if err := _Home.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) ParseGuardRemoved(log types.Log) (*HomeGuardRemoved, error) { + event := new(HomeGuardRemoved) + if err := _Home.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeImproperAttestationIterator is returned from FilterImproperAttestation and is used to iterate over the raw logs and unpacked data for ImproperAttestation events raised by the Home contract. +type HomeImproperAttestationIterator struct { + Event *HomeImproperAttestation // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeImproperAttestationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeImproperAttestation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeImproperAttestation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeImproperAttestationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeImproperAttestationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeImproperAttestation represents a ImproperAttestation event raised by the Home contract. +type HomeImproperAttestation struct { + Updater common.Address + Attestation []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) FilterImproperAttestation(opts *bind.FilterOpts) (*HomeImproperAttestationIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "ImproperAttestation") + if err != nil { + return nil, err + } + return &HomeImproperAttestationIterator{contract: _Home.contract, event: "ImproperAttestation", logs: logs, sub: sub}, nil +} + +// WatchImproperAttestation is a free log subscription operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *HomeImproperAttestation) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "ImproperAttestation") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeImproperAttestation) + if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseImproperAttestation is a log parse operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) ParseImproperAttestation(log types.Log) (*HomeImproperAttestation, error) { + event := new(HomeImproperAttestation) + if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Home contract. +type HomeInitializedIterator struct { + Event *HomeInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeInitialized represents a Initialized event raised by the Home contract. +type HomeInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*HomeInitializedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &HomeInitializedIterator{contract: _Home.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *HomeInitialized) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeInitialized) + if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) ParseInitialized(log types.Log) (*HomeInitialized, error) { + event := new(HomeInitialized) + if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeNewUpdaterManagerIterator is returned from FilterNewUpdaterManager and is used to iterate over the raw logs and unpacked data for NewUpdaterManager events raised by the Home contract. +type HomeNewUpdaterManagerIterator struct { + Event *HomeNewUpdaterManager // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeNewUpdaterManagerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeNewUpdaterManager) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeNewUpdaterManager) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeNewUpdaterManagerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeNewUpdaterManagerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeNewUpdaterManager represents a NewUpdaterManager event raised by the Home contract. +type HomeNewUpdaterManager struct { + UpdaterManager common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) FilterNewUpdaterManager(opts *bind.FilterOpts) (*HomeNewUpdaterManagerIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdaterManager") + if err != nil { + return nil, err + } + return &HomeNewUpdaterManagerIterator{contract: _Home.contract, event: "NewUpdaterManager", logs: logs, sub: sub}, nil +} + +// WatchNewUpdaterManager is a free log subscription operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *HomeNewUpdaterManager) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdaterManager") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeNewUpdaterManager) + if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNewUpdaterManager is a log parse operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) ParseNewUpdaterManager(log types.Log) (*HomeNewUpdaterManager, error) { + event := new(HomeNewUpdaterManager) + if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Home contract. +type HomeOwnershipTransferredIterator struct { + Event *HomeOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeOwnershipTransferred represents a OwnershipTransferred event raised by the Home contract. +type HomeOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*HomeOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Home.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &HomeOwnershipTransferredIterator{contract: _Home.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *HomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Home.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeOwnershipTransferred) + if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) ParseOwnershipTransferred(log types.Log) (*HomeOwnershipTransferred, error) { + event := new(HomeOwnershipTransferred) + if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeUpdaterSlashedIterator is returned from FilterUpdaterSlashed and is used to iterate over the raw logs and unpacked data for UpdaterSlashed events raised by the Home contract. +type HomeUpdaterSlashedIterator struct { + Event *HomeUpdaterSlashed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeUpdaterSlashedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeUpdaterSlashed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeUpdaterSlashed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeUpdaterSlashedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeUpdaterSlashedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeUpdaterSlashed represents a UpdaterSlashed event raised by the Home contract. +type HomeUpdaterSlashed struct { + Updater common.Address + Reporter common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdaterSlashed is a free log retrieval operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// +// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) +func (_Home *HomeFilterer) FilterUpdaterSlashed(opts *bind.FilterOpts, updater []common.Address, reporter []common.Address) (*HomeUpdaterSlashedIterator, error) { + + var updaterRule []interface{} + for _, updaterItem := range updater { + updaterRule = append(updaterRule, updaterItem) + } + var reporterRule []interface{} + for _, reporterItem := range reporter { + reporterRule = append(reporterRule, reporterItem) + } + + logs, sub, err := _Home.contract.FilterLogs(opts, "UpdaterSlashed", updaterRule, reporterRule) + if err != nil { + return nil, err + } + return &HomeUpdaterSlashedIterator{contract: _Home.contract, event: "UpdaterSlashed", logs: logs, sub: sub}, nil +} + +// WatchUpdaterSlashed is a free log subscription operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// +// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) +func (_Home *HomeFilterer) WatchUpdaterSlashed(opts *bind.WatchOpts, sink chan<- *HomeUpdaterSlashed, updater []common.Address, reporter []common.Address) (event.Subscription, error) { + + var updaterRule []interface{} + for _, updaterItem := range updater { + updaterRule = append(updaterRule, updaterItem) + } + var reporterRule []interface{} + for _, reporterItem := range reporter { + reporterRule = append(reporterRule, reporterItem) + } + + logs, sub, err := _Home.contract.WatchLogs(opts, "UpdaterSlashed", updaterRule, reporterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeUpdaterSlashed) + if err := _Home.contract.UnpackLog(event, "UpdaterSlashed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdaterSlashed is a log parse operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// +// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) +func (_Home *HomeFilterer) ParseUpdaterSlashed(log types.Log) (*HomeUpdaterSlashed, error) { + event := new(HomeUpdaterSlashed) + if err := _Home.contract.UnpackLog(event, "UpdaterSlashed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeHarnessMetaData contains all meta data concerning the HomeHarness contract. +var HomeHarnessMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destination\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"}],\"name\":\"destinationAndNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"isNotary\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sensitiveValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"setFailed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newValue\",\"type\":\"uint256\"}],\"name\":\"setSensitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enumHome.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "522ae002": "MAX_MESSAGE_BODY_BYTES()", + "ffa1ad74": "VERSION()", + "9fe03fa2": "allGuards()", + "9817e315": "allNotaries()", + "06661abd": "count()", + "da180e70": "destinationAndNonce(uint32,uint32)", + "f7560e40": "dispatch(uint32,bytes32,uint32,bytes,bytes)", + "629ddf69": "getGuard(uint256)", + "c07dc7f5": "getNotary(uint256)", + "246c2449": "guardsAmount()", + "7ea97f40": "historicalRoots(uint256)", + "0afe7f90": "improperAttestation(bytes)", + "c4d66de8": "initialize(address)", + "f13eed97": "isNotary(address)", + "8d3638f4": "localDomain()", + "affed0e0": "nonce()", + "8e62e9ef": "notariesAmount()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "ebf0c717": "root()", + "089d2894": "sensitiveValue()", + "a1191a51": "setFailed(address)", + "48639d24": "setSensitiveValue(uint256)", + "b7bc563e": "setSystemMessenger(address)", + "9d54f419": "setUpdater(address)", + "9776120e": "setUpdaterManager(address)", + "c19d93fb": "state()", + "36e104de": "suggestUpdate()", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + "fd54b228": "tree()", + "9df6c8e1": "updaterManager()", + }, + Bin: "0x60c06040523480156200001157600080fd5b5060405162003a4138038062003a41833981016040819052620000349162000048565b63ffffffff16608081905260a05262000077565b6000602082840312156200005b57600080fd5b815163ffffffff811681146200007057600080fd5b9392505050565b60805160a051613996620000ab600039600061171101526000818161035d01528181610ce30152610ff001526139966000f3fe6080604052600436106101e35760003560e01c80639df6c8e111610102578063ccbdf9c911610095578063f2fde38b11610064578063f2fde38b146105fe578063f7560e401461061e578063fd54b22814610631578063ffa1ad741461064857600080fd5b8063ccbdf9c914610563578063da180e7014610590578063ebf0c717146105c9578063f13eed97146105de57600080fd5b8063b7bc563e116100d1578063b7bc563e146104bf578063c07dc7f5146104df578063c19d93fb146104ff578063c4d66de81461054357600080fd5b80639df6c8e1146104365780639fe03fa21461046c578063a1191a5114610481578063affed0e0146104a157600080fd5b8063715018a61161017a5780638e62e9ef116101495780638e62e9ef146103bf5780639776120e146103d45780639817e315146103f45780639d54f4191461041657600080fd5b8063715018a6146103165780637ea97f401461032b5780638d3638f41461034b5780638da5cb5b1461039457600080fd5b806336e104de116101b657806336e104de1461026857806348639d2414610299578063522ae002146102bb578063629ddf69146102d157600080fd5b806306661abd146101e8578063089d28941461020c5780630afe7f9014610223578063246c244914610253575b600080fd5b3480156101f457600080fd5b506020545b6040519081526020015b60405180910390f35b34801561021857600080fd5b506101f961014e5481565b34801561022f57600080fd5b5061024361023e3660046131c2565b61066f565b6040519015158152602001610203565b34801561025f57600080fd5b506101f96107c6565b34801561027457600080fd5b5061027d6107d7565b6040805163ffffffff9093168352602083019190915201610203565b3480156102a557600080fd5b506102b96102b43660046131f7565b61081e565b005b3480156102c757600080fd5b506101f961080081565b3480156102dd57600080fd5b506102f16102ec3660046131f7565b61082c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610203565b34801561032257600080fd5b506102b961083f565b34801561033757600080fd5b506101f96103463660046131f7565b6108a8565b34801561035757600080fd5b5061037f7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610203565b3480156103a057600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff166102f1565b3480156103cb57600080fd5b506101f96108c9565b3480156103e057600080fd5b506102b96103ef366004613232565b6108d5565b34801561040057600080fd5b50610409610948565b604051610203919061324f565b34801561042257600080fd5b506102b9610431366004613232565b610954565b34801561044257600080fd5b5061011e546102f190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561047857600080fd5b50610409610a15565b34801561048d57600080fd5b506102b961049c366004613232565b610a21565b3480156104ad57600080fd5b5061011e5461037f9063ffffffff1681565b3480156104cb57600080fd5b506102b96104da366004613232565b610a2a565b3480156104eb57600080fd5b506102f16104fa3660046131f7565b610ad8565b34801561050b57600080fd5b5061011e54610536907801000000000000000000000000000000000000000000000000900460ff1681565b60405161020391906132d8565b34801561054f57600080fd5b506102b961055e366004613232565b610ae5565b34801561056f57600080fd5b5060b7546102f19073ffffffffffffffffffffffffffffffffffffffff1681565b34801561059c57600080fd5b506105b06105ab36600461332d565b610caf565b60405167ffffffffffffffff9091168152602001610203565b3480156105d557600080fd5b506101f9610cd0565b3480156105ea57600080fd5b506102436105f9366004613232565b610cdc565b34801561060a57600080fd5b506102b9610619366004613232565b610d08565b6102b961062c366004613360565b610e01565b34801561063d57600080fd5b506020546101f99081565b34801561065457600080fd5b5061065d600081565b60405160ff9091168152602001610203565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156106a7576106a76132a9565b036106f95760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080610705846110fb565b91509150600061071a8262ffffff191661120b565b9050600061072d62ffffff19841661121f565b60215490915063ffffffff831610156107765760218263ffffffff1681548110610759576107596133ef565b906000526020600020015481036107765750600095945050505050565b61077f84611234565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516107b0929190613498565b60405180910390a160019450505050505b919050565b60006107d260eb61134c565b905090565b60215460009081908015610819576107f06001826134f6565b925060218363ffffffff168154811061080b5761080b6133ef565b906000526020600020015491505b509091565b610826611356565b61014e55565b600061083960eb836113bd565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b565b602181815481106108b857600080fd5b600091825260209091200154905081565b60006107d260b861134c565b60855473ffffffffffffffffffffffffffffffffffffffff16331461093c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b610945816113c9565b50565b60606107d260b86114b1565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146109c45760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e61676572000000000000000000000000000000000060448201526064016106f0565b6109cd816114be565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606107d260eb6114b1565b61094581611234565b60855473ffffffffffffffffffffffffffffffffffffffff163314610a915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061083960b8836113bd565b6000610af16001611521565b90508015610b2657605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b2e611675565b610b37826113c9565b610bd161011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ba8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcc919061350d565b6114be565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610cab57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600067ffffffff00000000602084901b1663ffffffff8316175b9392505050565b60006107d260006116fa565b60006108397f00000000000000000000000000000000000000000000000000000000000000008361170d565b60855473ffffffffffffffffffffffffffffffffffffffff163314610d6f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b73ffffffffffffffffffffffffffffffffffffffff8116610df85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106f0565b61094581611795565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610e3757610e376132a9565b03610e845760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064016106f0565b61080081511115610ed75760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e67000000000000000000000000000000000000000060448201526064016106f0565b34610eef610ee48461180c565b62ffffff1916611819565b6bffffffffffffffffffffffff1614610f4a5760405162461bcd60e51b815260206004820152600560248201527f217469707300000000000000000000000000000000000000000000000000000060448201526064016106f0565b61011e54610f5f9063ffffffff16600161352a565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610fa08561187b565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e8301528051808303605201815260729092019052909150600061106a8286866118da565b8051602082012090915061107d81611954565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff1660016110ac60205490565b6110b691906134f6565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e78589866040516110e8929190613552565b60405180910390a4505050505050505050565b6000806111088382611984565b905060286bffffffffffffffffffffffff601883901c161161116c5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016106f0565b6111a061117e62ffffff1983166119a8565b61119b61119062ffffff1985166119bd565b62ffffff19166119f0565b611a43565b91506111ba6111b462ffffff198316611ac2565b8361170d565b6112065760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f746172790000000000000000000060448201526064016106f0565b915091565b600061083962ffffff198316600480611ad2565b600061083962ffffff19831660086020611b02565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156112ee57600080fd5b505af1158015611302573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610839825490565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146108a65760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e6765720000000000000000000000000000000060448201526064016106f0565b6000610cc98383611cc0565b73ffffffffffffffffffffffffffffffffffffffff81163b61142d5760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e61676572000000000000000060448201526064016106f0565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60606000610cc983611cea565b60006114cb60b883611d46565b905080156107c15760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff16156115c0578160ff1660011480156115465750303b155b6115b85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106f0565b506000919050565b60525460ff80841691161061163d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106f0565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166116f25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f0565b6108a6611d68565b600061083982611708611dee565b6122af565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461178a5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e000000000000000000000000000000000000000060448201526064016106f0565b610cc960b883612372565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610839826002611984565b60008161182f60025b62ffffff198316906123a1565b50611839836124a2565b611842846124d0565b61184b856124f1565b61185486612512565b61185e9190613577565b6118689190613577565b6118729190613577565b91505b50919050565b60007fffffffffffffffffffffffff000000000000000000000000000000000000000082146118ab573392915050565b6118b3611356565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906118ee6004600261359e565b60ff166118fb91906135c7565b9050600084518261190c91906135c7565b9050600161191c6004600261359e565b60ff16838389898960405160200161193a97969594939291906135e4565b604051602081830303815290604052925050509392505050565b61195f600082612533565b602161196b60006116fa565b8154600181018355600092835260209092209091015550565b81516000906020840161199f64ffffffffff85168284612656565b95945050505050565b600061083962ffffff1983168260288161269d565b600061083960286119e081601886901c6bffffffffffffffffffffffff166134f6565b62ffffff1985169190600061269d565b6060600080611a0d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506040519150819250611a328483602001612721565b508181016020016040529052919050565b600080611a5562ffffff1985166128bc565b9050611aae816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9050611aba8184612919565b949350505050565b600061083962ffffff1983168260045b6000611adf826020613682565b611aea90600861359e565b60ff16611af8858585611b02565b901c949350505050565b60008160ff16600003611b1757506000610cc9565b611b2f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611b4a60ff8416856136a5565b1115611bc257611ba9611b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611b918660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661293d565b60405162461bcd60e51b81526004016106f091906136bd565b60208260ff161115611c3c5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016106f0565b600882026000611c5a8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611cd757611cd76133ef565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611d3a57602002820191906000526020600020905b815481526020019060010190808311611d26575b50505050509050919050565b6000610cc98373ffffffffffffffffffffffffffffffffffffffff84166129ab565b605254610100900460ff16611de55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f0565b6108a633611795565b611df66130c9565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561236a57600182821c811690819003612316578582602081106122e3576122e36133ef565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612361565b83858360208110612329576123296133ef565b6020020151604051602001612348929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016122b9565b505092915050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610cc9565b60006123ad83836129fa565b61249b5760006123cc6123c08560d81c90565b64ffffffffff16612a1d565b91505060006123e18464ffffffffff16612a1d565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016106f091906136bd565b5090919050565b6000816124af6002611822565b506124c362ffffff1984166026600c611ad2565b63ffffffff169392505050565b6000816124dd6002611822565b506124c362ffffff198416601a600c611ad2565b6000816124fe6002611822565b506124c362ffffff198416600e600c611ad2565b60008161251f6002611822565b506124c362ffffff1984166002600c611ad2565b602080830154906001906125489060026137e8565b61255291906134f6565b81106125a05760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c0000000000000000000000000000000060448201526064016106f0565b6001016020830181905560005b602081101561264857816001166001036125dc57828482602081106125d4576125d46133ef565b015550505050565b8381602081106125ee576125ee6133ef565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016125ad565b506126516137f4565b505050565b60008061266383856136a5565b9050604051811115612673575060005b806000036126885762ffffff19915050610cc9565b5050606092831b9190911790911b1760181b90565b6000806126b88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506126d186612b07565b846126dc87846136a5565b6126e691906136a5565b11156126f95762ffffff19915050611aba565b61270385826136a5565b90506127178364ffffffffff168286612656565b9695505050505050565b600062ffffff198084160361279e5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016106f0565b6127a783612b4f565b6128195760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016106f0565b60006128338460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061285d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156128825760206060fd5b8285848460045afa506127176128988760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806128d78360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006129018460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006129288585612b8c565b9150915061293581612bfa565b509392505050565b6060600061294a86612a1d565b915050600061295886612a1d565b915050600061296686612a1d565b915050600061297486612a1d565b9150508383838360405160200161298e9493929190613823565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546129f257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610839565b506000610839565b60008164ffffffffff16612a0e8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115612a90576000612a3c82600861359e565b60ff1685901c9050612a4d81612de6565b61ffff16841793508160ff16601014612a6857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612a23565b50600f5b60ff8160ff161015612b01576000612aad82600861359e565b60ff1685901c9050612abe81612de6565b61ffff16831792508160ff16600014612ad957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612a94565b50915091565b6000612b218260181c6bffffffffffffffffffffffff1690565b612b398360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612b5b8260d81c90565b64ffffffffff1664ffffffffff03612b7557506000919050565b6000612b8083612b07565b60405110199392505050565b6000808251604103612bc25760208301516040840151606085015160001a612bb687828585612e18565b94509450505050612bf3565b8251604003612beb5760208301516040840151612be0868383612f30565b935093505050612bf3565b506000905060025b9250929050565b6000816004811115612c0e57612c0e6132a9565b03612c165750565b6001816004811115612c2a57612c2a6132a9565b03612c775760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106f0565b6002816004811115612c8b57612c8b6132a9565b03612cd85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106f0565b6003816004811115612cec57612cec6132a9565b03612d5f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016106f0565b6004816004811115612d7357612d736132a9565b036109455760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016106f0565b6000612df860048360ff16901c612f82565b60ff1661ffff919091161760081b612e0f82612f82565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612e4f5750600090506003612f27565b8460ff16601b14158015612e6757508460ff16601c14155b15612e785750600090506004612f27565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612ecc573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612f2057600060019250925050612f27565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612f6660ff86901c601b6136a5565b9050612f7487828885612e18565b935093505050935093915050565b600060f08083179060ff82169003612f9d5750603092915050565b8060ff1660f103612fb15750603192915050565b8060ff1660f203612fc55750603292915050565b8060ff1660f303612fd95750603392915050565b8060ff1660f403612fed5750603492915050565b8060ff1660f5036130015750603592915050565b8060ff1660f6036130155750603692915050565b8060ff1660f7036130295750603792915050565b8060ff1660f80361303d5750603892915050565b8060ff1660f9036130515750603992915050565b8060ff1660fa036130655750606192915050565b8060ff1660fb036130795750606292915050565b8060ff1660fc0361308d5750606392915050565b8060ff1660fd036130a15750606492915050565b8060ff1660fe036130b55750606592915050565b8060ff1660ff036118755750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261312857600080fd5b813567ffffffffffffffff80821115613143576131436130e8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613189576131896130e8565b816040528381528660208588010111156131a257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000602082840312156131d457600080fd5b813567ffffffffffffffff8111156131eb57600080fd5b611aba84828501613117565b60006020828403121561320957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461094557600080fd5b60006020828403121561324457600080fd5b8135610cc981613210565b6020808252825182820181905260009190848201906040850190845b8181101561329d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161326b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310613313577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146107c157600080fd5b6000806040838503121561334057600080fd5b61334983613319565b915061335760208401613319565b90509250929050565b600080600080600060a0868803121561337857600080fd5b61338186613319565b94506020860135935061339660408701613319565b9250606086013567ffffffffffffffff808211156133b357600080fd5b6133bf89838a01613117565b935060808801359150808211156133d557600080fd5b506133e288828901613117565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b83811015613439578181015183820152602001613421565b83811115613448576000848401525b50505050565b6000815180845261346681602086016020860161341e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aba604083018461344e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015613508576135086134c7565b500390565b60006020828403121561351f57600080fd5b8151610cc981613210565b600063ffffffff808316818516808303821115613549576135496134c7565b01949350505050565b604081526000613565604083018561344e565b828103602084015261199f818561344e565b60006bffffffffffffffffffffffff808316818516808303821115613549576135496134c7565b600060ff821660ff84168160ff04811182151516156135bf576135bf6134c7565b029392505050565b600061ffff808316818516808303821115613549576135496134c7565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b16600684015250845161364481600885016020890161341e565b84519083019061365b81600884016020890161341e565b845191019061367181600884016020880161341e565b016008019998505050505050505050565b600060ff821660ff84168082101561369c5761369c6134c7565b90039392505050565b600082198211156136b8576136b86134c7565b500190565b602081526000610cc9602083018461344e565b600181815b8085111561372957817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561370f5761370f6134c7565b8085161561371c57918102915b93841c93908002906136d5565b509250929050565b60008261374057506001610839565b8161374d57506000610839565b8160018114613763576002811461376d57613789565b6001915050610839565b60ff84111561377e5761377e6134c7565b50506001821b610839565b5060208310610133831016604e8410600b84101617156137ac575081810a610839565b6137b683836136d0565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156135bf576135bf6134c7565b6000610cc98383613731565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161271756fea264697066735822122009bcaead08729c8a3a797dab376fd9e8a037e4d92ffac1cbe9fe31c138d679fa64736f6c634300080d0033", +} + +// HomeHarnessABI is the input ABI used to generate the binding from. +// Deprecated: Use HomeHarnessMetaData.ABI instead. +var HomeHarnessABI = HomeHarnessMetaData.ABI + +// Deprecated: Use HomeHarnessMetaData.Sigs instead. +// HomeHarnessFuncSigs maps the 4-byte function signature to its string representation. +var HomeHarnessFuncSigs = HomeHarnessMetaData.Sigs + +// HomeHarnessBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HomeHarnessMetaData.Bin instead. +var HomeHarnessBin = HomeHarnessMetaData.Bin + +// DeployHomeHarness deploys a new Ethereum contract, binding an instance of HomeHarness to it. +func DeployHomeHarness(auth *bind.TransactOpts, backend bind.ContractBackend, _domain uint32) (common.Address, *types.Transaction, *HomeHarness, error) { + parsed, err := HomeHarnessMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HomeHarnessBin), backend, _domain) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &HomeHarness{HomeHarnessCaller: HomeHarnessCaller{contract: contract}, HomeHarnessTransactor: HomeHarnessTransactor{contract: contract}, HomeHarnessFilterer: HomeHarnessFilterer{contract: contract}}, nil +} + +// HomeHarness is an auto generated Go binding around an Ethereum contract. +type HomeHarness struct { + HomeHarnessCaller // Read-only binding to the contract + HomeHarnessTransactor // Write-only binding to the contract + HomeHarnessFilterer // Log filterer for contract events +} + +// HomeHarnessCaller is an auto generated read-only Go binding around an Ethereum contract. +type HomeHarnessCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// HomeHarnessTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HomeHarnessTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// HomeHarnessFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HomeHarnessFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// HomeHarnessSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type HomeHarnessSession struct { + Contract *HomeHarness // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// HomeHarnessCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type HomeHarnessCallerSession struct { + Contract *HomeHarnessCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// HomeHarnessTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type HomeHarnessTransactorSession struct { + Contract *HomeHarnessTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// HomeHarnessRaw is an auto generated low-level Go binding around an Ethereum contract. +type HomeHarnessRaw struct { + Contract *HomeHarness // Generic contract binding to access the raw methods on +} + +// HomeHarnessCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HomeHarnessCallerRaw struct { + Contract *HomeHarnessCaller // Generic read-only contract binding to access the raw methods on +} + +// HomeHarnessTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HomeHarnessTransactorRaw struct { + Contract *HomeHarnessTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewHomeHarness creates a new instance of HomeHarness, bound to a specific deployed contract. +func NewHomeHarness(address common.Address, backend bind.ContractBackend) (*HomeHarness, error) { + contract, err := bindHomeHarness(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &HomeHarness{HomeHarnessCaller: HomeHarnessCaller{contract: contract}, HomeHarnessTransactor: HomeHarnessTransactor{contract: contract}, HomeHarnessFilterer: HomeHarnessFilterer{contract: contract}}, nil +} + +// NewHomeHarnessCaller creates a new read-only instance of HomeHarness, bound to a specific deployed contract. +func NewHomeHarnessCaller(address common.Address, caller bind.ContractCaller) (*HomeHarnessCaller, error) { + contract, err := bindHomeHarness(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &HomeHarnessCaller{contract: contract}, nil +} + +// NewHomeHarnessTransactor creates a new write-only instance of HomeHarness, bound to a specific deployed contract. +func NewHomeHarnessTransactor(address common.Address, transactor bind.ContractTransactor) (*HomeHarnessTransactor, error) { + contract, err := bindHomeHarness(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &HomeHarnessTransactor{contract: contract}, nil +} + +// NewHomeHarnessFilterer creates a new log filterer instance of HomeHarness, bound to a specific deployed contract. +func NewHomeHarnessFilterer(address common.Address, filterer bind.ContractFilterer) (*HomeHarnessFilterer, error) { + contract, err := bindHomeHarness(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &HomeHarnessFilterer{contract: contract}, nil +} + +// bindHomeHarness binds a generic wrapper to an already deployed contract. +func bindHomeHarness(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HomeHarnessABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_HomeHarness *HomeHarnessRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _HomeHarness.Contract.HomeHarnessCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_HomeHarness *HomeHarnessRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _HomeHarness.Contract.HomeHarnessTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_HomeHarness *HomeHarnessRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _HomeHarness.Contract.HomeHarnessTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_HomeHarness *HomeHarnessCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _HomeHarness.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_HomeHarness *HomeHarnessTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _HomeHarness.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_HomeHarness *HomeHarnessTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _HomeHarness.Contract.contract.Transact(opts, method, params...) +} + +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_HomeHarness *HomeHarnessCaller) MAXMESSAGEBODYBYTES(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "MAX_MESSAGE_BODY_BYTES") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_HomeHarness *HomeHarnessSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { + return _HomeHarness.Contract.MAXMESSAGEBODYBYTES(&_HomeHarness.CallOpts) +} + +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_HomeHarness *HomeHarnessCallerSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { + return _HomeHarness.Contract.MAXMESSAGEBODYBYTES(&_HomeHarness.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_HomeHarness *HomeHarnessCaller) VERSION(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "VERSION") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_HomeHarness *HomeHarnessSession) VERSION() (uint8, error) { + return _HomeHarness.Contract.VERSION(&_HomeHarness.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_HomeHarness *HomeHarnessCallerSession) VERSION() (uint8, error) { + return _HomeHarness.Contract.VERSION(&_HomeHarness.CallOpts) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_HomeHarness *HomeHarnessCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "allGuards") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_HomeHarness *HomeHarnessSession) AllGuards() ([]common.Address, error) { + return _HomeHarness.Contract.AllGuards(&_HomeHarness.CallOpts) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_HomeHarness *HomeHarnessCallerSession) AllGuards() ([]common.Address, error) { + return _HomeHarness.Contract.AllGuards(&_HomeHarness.CallOpts) +} + +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_HomeHarness *HomeHarnessCaller) AllNotaries(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "allNotaries") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_HomeHarness *HomeHarnessSession) AllNotaries() ([]common.Address, error) { + return _HomeHarness.Contract.AllNotaries(&_HomeHarness.CallOpts) +} + +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_HomeHarness *HomeHarnessCallerSession) AllNotaries() ([]common.Address, error) { + return _HomeHarness.Contract.AllNotaries(&_HomeHarness.CallOpts) +} + +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_HomeHarness *HomeHarnessCaller) Count(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "count") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_HomeHarness *HomeHarnessSession) Count() (*big.Int, error) { + return _HomeHarness.Contract.Count(&_HomeHarness.CallOpts) +} + +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_HomeHarness *HomeHarnessCallerSession) Count() (*big.Int, error) { + return _HomeHarness.Contract.Count(&_HomeHarness.CallOpts) +} + +// DestinationAndNonce is a free data retrieval call binding the contract method 0xda180e70. +// +// Solidity: function destinationAndNonce(uint32 _destination, uint32 _nonce) pure returns(uint64) +func (_HomeHarness *HomeHarnessCaller) DestinationAndNonce(opts *bind.CallOpts, _destination uint32, _nonce uint32) (uint64, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "destinationAndNonce", _destination, _nonce) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// DestinationAndNonce is a free data retrieval call binding the contract method 0xda180e70. +// +// Solidity: function destinationAndNonce(uint32 _destination, uint32 _nonce) pure returns(uint64) +func (_HomeHarness *HomeHarnessSession) DestinationAndNonce(_destination uint32, _nonce uint32) (uint64, error) { + return _HomeHarness.Contract.DestinationAndNonce(&_HomeHarness.CallOpts, _destination, _nonce) +} + +// DestinationAndNonce is a free data retrieval call binding the contract method 0xda180e70. +// +// Solidity: function destinationAndNonce(uint32 _destination, uint32 _nonce) pure returns(uint64) +func (_HomeHarness *HomeHarnessCallerSession) DestinationAndNonce(_destination uint32, _nonce uint32) (uint64, error) { + return _HomeHarness.Contract.DestinationAndNonce(&_HomeHarness.CallOpts, _destination, _nonce) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_HomeHarness *HomeHarnessCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "getGuard", _index) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_HomeHarness *HomeHarnessSession) GetGuard(_index *big.Int) (common.Address, error) { + return _HomeHarness.Contract.GetGuard(&_HomeHarness.CallOpts, _index) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_HomeHarness *HomeHarnessCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _HomeHarness.Contract.GetGuard(&_HomeHarness.CallOpts, _index) +} + +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_HomeHarness *HomeHarnessCaller) GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "getNotary", _index) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_HomeHarness *HomeHarnessSession) GetNotary(_index *big.Int) (common.Address, error) { + return _HomeHarness.Contract.GetNotary(&_HomeHarness.CallOpts, _index) +} + +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_HomeHarness *HomeHarnessCallerSession) GetNotary(_index *big.Int) (common.Address, error) { + return _HomeHarness.Contract.GetNotary(&_HomeHarness.CallOpts, _index) +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_HomeHarness *HomeHarnessCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "guardsAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_HomeHarness *HomeHarnessSession) GuardsAmount() (*big.Int, error) { + return _HomeHarness.Contract.GuardsAmount(&_HomeHarness.CallOpts) +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_HomeHarness *HomeHarnessCallerSession) GuardsAmount() (*big.Int, error) { + return _HomeHarness.Contract.GuardsAmount(&_HomeHarness.CallOpts) +} + +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_HomeHarness *HomeHarnessCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "historicalRoots", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_HomeHarness *HomeHarnessSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _HomeHarness.Contract.HistoricalRoots(&_HomeHarness.CallOpts, arg0) +} + +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_HomeHarness *HomeHarnessCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _HomeHarness.Contract.HistoricalRoots(&_HomeHarness.CallOpts, arg0) +} + +// IsNotary is a free data retrieval call binding the contract method 0xf13eed97. +// +// Solidity: function isNotary(address _notary) view returns(bool) +func (_HomeHarness *HomeHarnessCaller) IsNotary(opts *bind.CallOpts, _notary common.Address) (bool, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "isNotary", _notary) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsNotary is a free data retrieval call binding the contract method 0xf13eed97. +// +// Solidity: function isNotary(address _notary) view returns(bool) +func (_HomeHarness *HomeHarnessSession) IsNotary(_notary common.Address) (bool, error) { + return _HomeHarness.Contract.IsNotary(&_HomeHarness.CallOpts, _notary) +} + +// IsNotary is a free data retrieval call binding the contract method 0xf13eed97. +// +// Solidity: function isNotary(address _notary) view returns(bool) +func (_HomeHarness *HomeHarnessCallerSession) IsNotary(_notary common.Address) (bool, error) { + return _HomeHarness.Contract.IsNotary(&_HomeHarness.CallOpts, _notary) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_HomeHarness *HomeHarnessCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_HomeHarness *HomeHarnessSession) LocalDomain() (uint32, error) { + return _HomeHarness.Contract.LocalDomain(&_HomeHarness.CallOpts) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_HomeHarness *HomeHarnessCallerSession) LocalDomain() (uint32, error) { + return _HomeHarness.Contract.LocalDomain(&_HomeHarness.CallOpts) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint32) +func (_HomeHarness *HomeHarnessCaller) Nonce(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "nonce") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint32) +func (_HomeHarness *HomeHarnessSession) Nonce() (uint32, error) { + return _HomeHarness.Contract.Nonce(&_HomeHarness.CallOpts) +} + +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint32) +func (_HomeHarness *HomeHarnessCallerSession) Nonce() (uint32, error) { + return _HomeHarness.Contract.Nonce(&_HomeHarness.CallOpts) +} + +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_HomeHarness *HomeHarnessCaller) NotariesAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "notariesAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_HomeHarness *HomeHarnessSession) NotariesAmount() (*big.Int, error) { + return _HomeHarness.Contract.NotariesAmount(&_HomeHarness.CallOpts) +} + +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_HomeHarness *HomeHarnessCallerSession) NotariesAmount() (*big.Int, error) { + return _HomeHarness.Contract.NotariesAmount(&_HomeHarness.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_HomeHarness *HomeHarnessCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_HomeHarness *HomeHarnessSession) Owner() (common.Address, error) { + return _HomeHarness.Contract.Owner(&_HomeHarness.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_HomeHarness *HomeHarnessCallerSession) Owner() (common.Address, error) { + return _HomeHarness.Contract.Owner(&_HomeHarness.CallOpts) +} + +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_HomeHarness *HomeHarnessCaller) Root(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "root") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_HomeHarness *HomeHarnessSession) Root() ([32]byte, error) { + return _HomeHarness.Contract.Root(&_HomeHarness.CallOpts) +} + +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_HomeHarness *HomeHarnessCallerSession) Root() ([32]byte, error) { + return _HomeHarness.Contract.Root(&_HomeHarness.CallOpts) +} + +// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// +// Solidity: function sensitiveValue() view returns(uint256) +func (_HomeHarness *HomeHarnessCaller) SensitiveValue(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "sensitiveValue") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// +// Solidity: function sensitiveValue() view returns(uint256) +func (_HomeHarness *HomeHarnessSession) SensitiveValue() (*big.Int, error) { + return _HomeHarness.Contract.SensitiveValue(&_HomeHarness.CallOpts) +} + +// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// +// Solidity: function sensitiveValue() view returns(uint256) +func (_HomeHarness *HomeHarnessCallerSession) SensitiveValue() (*big.Int, error) { + return _HomeHarness.Contract.SensitiveValue(&_HomeHarness.CallOpts) +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_HomeHarness *HomeHarnessCaller) State(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "state") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_HomeHarness *HomeHarnessSession) State() (uint8, error) { + return _HomeHarness.Contract.State(&_HomeHarness.CallOpts) +} + +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_HomeHarness *HomeHarnessCallerSession) State() (uint8, error) { + return _HomeHarness.Contract.State(&_HomeHarness.CallOpts) +} + +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_HomeHarness *HomeHarnessCaller) SuggestUpdate(opts *bind.CallOpts) (struct { + Nonce uint32 + Root [32]byte +}, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "suggestUpdate") + + outstruct := new(struct { + Nonce uint32 + Root [32]byte + }) + if err != nil { + return *outstruct, err + } + + outstruct.Nonce = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_HomeHarness *HomeHarnessSession) SuggestUpdate() (struct { + Nonce uint32 + Root [32]byte +}, error) { + return _HomeHarness.Contract.SuggestUpdate(&_HomeHarness.CallOpts) +} + +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_HomeHarness *HomeHarnessCallerSession) SuggestUpdate() (struct { + Nonce uint32 + Root [32]byte +}, error) { + return _HomeHarness.Contract.SuggestUpdate(&_HomeHarness.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_HomeHarness *HomeHarnessCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "systemMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_HomeHarness *HomeHarnessSession) SystemMessenger() (common.Address, error) { + return _HomeHarness.Contract.SystemMessenger(&_HomeHarness.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_HomeHarness *HomeHarnessCallerSession) SystemMessenger() (common.Address, error) { + return _HomeHarness.Contract.SystemMessenger(&_HomeHarness.CallOpts) +} + +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_HomeHarness *HomeHarnessCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "tree") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_HomeHarness *HomeHarnessSession) Tree() (*big.Int, error) { + return _HomeHarness.Contract.Tree(&_HomeHarness.CallOpts) +} + +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_HomeHarness *HomeHarnessCallerSession) Tree() (*big.Int, error) { + return _HomeHarness.Contract.Tree(&_HomeHarness.CallOpts) +} + +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_HomeHarness *HomeHarnessCaller) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _HomeHarness.contract.Call(opts, &out, "updaterManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_HomeHarness *HomeHarnessSession) UpdaterManager() (common.Address, error) { + return _HomeHarness.Contract.UpdaterManager(&_HomeHarness.CallOpts) +} + +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_HomeHarness *HomeHarnessCallerSession) UpdaterManager() (common.Address, error) { + return _HomeHarness.Contract.UpdaterManager(&_HomeHarness.CallOpts) +} + +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_HomeHarness *HomeHarnessTransactor) Dispatch(opts *bind.TransactOpts, _destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "dispatch", _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) +} + +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_HomeHarness *HomeHarnessSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _HomeHarness.Contract.Dispatch(&_HomeHarness.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) +} + +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_HomeHarness *HomeHarnessTransactorSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _HomeHarness.Contract.Dispatch(&_HomeHarness.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) +} + +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_HomeHarness *HomeHarnessTransactor) ImproperAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "improperAttestation", _attestation) +} + +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_HomeHarness *HomeHarnessSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { + return _HomeHarness.Contract.ImproperAttestation(&_HomeHarness.TransactOpts, _attestation) +} + +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_HomeHarness *HomeHarnessTransactorSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { + return _HomeHarness.Contract.ImproperAttestation(&_HomeHarness.TransactOpts, _attestation) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address _updaterManager) returns() +func (_HomeHarness *HomeHarnessTransactor) Initialize(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "initialize", _updaterManager) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address _updaterManager) returns() +func (_HomeHarness *HomeHarnessSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.Initialize(&_HomeHarness.TransactOpts, _updaterManager) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address _updaterManager) returns() +func (_HomeHarness *HomeHarnessTransactorSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.Initialize(&_HomeHarness.TransactOpts, _updaterManager) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_HomeHarness *HomeHarnessTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_HomeHarness *HomeHarnessSession) RenounceOwnership() (*types.Transaction, error) { + return _HomeHarness.Contract.RenounceOwnership(&_HomeHarness.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_HomeHarness *HomeHarnessTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _HomeHarness.Contract.RenounceOwnership(&_HomeHarness.TransactOpts) +} + +// SetFailed is a paid mutator transaction binding the contract method 0xa1191a51. +// +// Solidity: function setFailed(address _notary) returns() +func (_HomeHarness *HomeHarnessTransactor) SetFailed(opts *bind.TransactOpts, _notary common.Address) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "setFailed", _notary) +} + +// SetFailed is a paid mutator transaction binding the contract method 0xa1191a51. +// +// Solidity: function setFailed(address _notary) returns() +func (_HomeHarness *HomeHarnessSession) SetFailed(_notary common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.SetFailed(&_HomeHarness.TransactOpts, _notary) +} + +// SetFailed is a paid mutator transaction binding the contract method 0xa1191a51. +// +// Solidity: function setFailed(address _notary) returns() +func (_HomeHarness *HomeHarnessTransactorSession) SetFailed(_notary common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.SetFailed(&_HomeHarness.TransactOpts, _notary) +} + +// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. +// +// Solidity: function setSensitiveValue(uint256 _newValue) returns() +func (_HomeHarness *HomeHarnessTransactor) SetSensitiveValue(opts *bind.TransactOpts, _newValue *big.Int) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "setSensitiveValue", _newValue) +} + +// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. +// +// Solidity: function setSensitiveValue(uint256 _newValue) returns() +func (_HomeHarness *HomeHarnessSession) SetSensitiveValue(_newValue *big.Int) (*types.Transaction, error) { + return _HomeHarness.Contract.SetSensitiveValue(&_HomeHarness.TransactOpts, _newValue) +} + +// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. +// +// Solidity: function setSensitiveValue(uint256 _newValue) returns() +func (_HomeHarness *HomeHarnessTransactorSession) SetSensitiveValue(_newValue *big.Int) (*types.Transaction, error) { + return _HomeHarness.Contract.SetSensitiveValue(&_HomeHarness.TransactOpts, _newValue) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_HomeHarness *HomeHarnessTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_HomeHarness *HomeHarnessSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.SetSystemMessenger(&_HomeHarness.TransactOpts, _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_HomeHarness *HomeHarnessTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.SetSystemMessenger(&_HomeHarness.TransactOpts, _systemMessenger) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_HomeHarness *HomeHarnessTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "setUpdater", _updater) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_HomeHarness *HomeHarnessSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.SetUpdater(&_HomeHarness.TransactOpts, _updater) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_HomeHarness *HomeHarnessTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.SetUpdater(&_HomeHarness.TransactOpts, _updater) +} + +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_HomeHarness *HomeHarnessTransactor) SetUpdaterManager(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "setUpdaterManager", _updaterManager) +} + +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_HomeHarness *HomeHarnessSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.SetUpdaterManager(&_HomeHarness.TransactOpts, _updaterManager) +} + +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_HomeHarness *HomeHarnessTransactorSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.SetUpdaterManager(&_HomeHarness.TransactOpts, _updaterManager) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_HomeHarness *HomeHarnessTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _HomeHarness.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_HomeHarness *HomeHarnessSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.TransferOwnership(&_HomeHarness.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_HomeHarness *HomeHarnessTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _HomeHarness.Contract.TransferOwnership(&_HomeHarness.TransactOpts, newOwner) +} + +// HomeHarnessDispatchIterator is returned from FilterDispatch and is used to iterate over the raw logs and unpacked data for Dispatch events raised by the HomeHarness contract. +type HomeHarnessDispatchIterator struct { + Event *HomeHarnessDispatch // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeHarnessDispatchIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeHarnessDispatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeHarnessDispatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeHarnessDispatchIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeHarnessDispatchIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeHarnessDispatch represents a Dispatch event raised by the HomeHarness contract. +type HomeHarnessDispatch struct { + MessageHash [32]byte + LeafIndex *big.Int + DestinationAndNonce uint64 + Tips []byte + Message []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDispatch is a free log retrieval operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_HomeHarness *HomeHarnessFilterer) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (*HomeHarnessDispatchIterator, error) { + + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) + } + var leafIndexRule []interface{} + for _, leafIndexItem := range leafIndex { + leafIndexRule = append(leafIndexRule, leafIndexItem) + } + var destinationAndNonceRule []interface{} + for _, destinationAndNonceItem := range destinationAndNonce { + destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) + } + + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + if err != nil { + return nil, err + } + return &HomeHarnessDispatchIterator{contract: _HomeHarness.contract, event: "Dispatch", logs: logs, sub: sub}, nil +} + +// WatchDispatch is a free log subscription operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_HomeHarness *HomeHarnessFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *HomeHarnessDispatch, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (event.Subscription, error) { + + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) + } + var leafIndexRule []interface{} + for _, leafIndexItem := range leafIndex { + leafIndexRule = append(leafIndexRule, leafIndexItem) + } + var destinationAndNonceRule []interface{} + for _, destinationAndNonceItem := range destinationAndNonce { + destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) + } + + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeHarnessDispatch) + if err := _HomeHarness.contract.UnpackLog(event, "Dispatch", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDispatch is a log parse operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_HomeHarness *HomeHarnessFilterer) ParseDispatch(log types.Log) (*HomeHarnessDispatch, error) { + event := new(HomeHarnessDispatch) + if err := _HomeHarness.contract.UnpackLog(event, "Dispatch", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeHarnessDomainNotaryAddedIterator is returned from FilterDomainNotaryAdded and is used to iterate over the raw logs and unpacked data for DomainNotaryAdded events raised by the HomeHarness contract. +type HomeHarnessDomainNotaryAddedIterator struct { + Event *HomeHarnessDomainNotaryAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeHarnessDomainNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeHarnessDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeHarnessDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeHarnessDomainNotaryAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeHarnessDomainNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeHarnessDomainNotaryAdded represents a DomainNotaryAdded event raised by the HomeHarness contract. +type HomeHarnessDomainNotaryAdded struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDomainNotaryAdded is a free log retrieval operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_HomeHarness *HomeHarnessFilterer) FilterDomainNotaryAdded(opts *bind.FilterOpts) (*HomeHarnessDomainNotaryAddedIterator, error) { + + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "DomainNotaryAdded") + if err != nil { + return nil, err + } + return &HomeHarnessDomainNotaryAddedIterator{contract: _HomeHarness.contract, event: "DomainNotaryAdded", logs: logs, sub: sub}, nil +} + +// WatchDomainNotaryAdded is a free log subscription operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_HomeHarness *HomeHarnessFilterer) WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *HomeHarnessDomainNotaryAdded) (event.Subscription, error) { + + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "DomainNotaryAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeHarnessDomainNotaryAdded) + if err := _HomeHarness.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// ParseDomainNotaryAdded is a log parse operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_HomeHarness *HomeHarnessTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _HomeHarness.Contract.TransferOwnership(&_HomeHarness.TransactOpts, newOwner) +// Solidity: event DomainNotaryAdded(address notary) +func (_HomeHarness *HomeHarnessFilterer) ParseDomainNotaryAdded(log types.Log) (*HomeHarnessDomainNotaryAdded, error) { + event := new(HomeHarnessDomainNotaryAdded) + if err := _HomeHarness.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// HomeHarnessDispatchIterator is returned from FilterDispatch and is used to iterate over the raw logs and unpacked data for Dispatch events raised by the HomeHarness contract. -type HomeHarnessDispatchIterator struct { - Event *HomeHarnessDispatch // Event containing the contract specifics and raw log +// HomeHarnessDomainNotaryRemovedIterator is returned from FilterDomainNotaryRemoved and is used to iterate over the raw logs and unpacked data for DomainNotaryRemoved events raised by the HomeHarness contract. +type HomeHarnessDomainNotaryRemovedIterator struct { + Event *HomeHarnessDomainNotaryRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4431,7 +6729,7 @@ type HomeHarnessDispatchIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeHarnessDispatchIterator) Next() bool { +func (it *HomeHarnessDomainNotaryRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4440,7 +6738,7 @@ func (it *HomeHarnessDispatchIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeHarnessDispatch) + it.Event = new(HomeHarnessDomainNotaryRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4455,7 +6753,7 @@ func (it *HomeHarnessDispatchIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeHarnessDispatch) + it.Event = new(HomeHarnessDomainNotaryRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4471,71 +6769,41 @@ func (it *HomeHarnessDispatchIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeHarnessDispatchIterator) Error() error { +func (it *HomeHarnessDomainNotaryRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeHarnessDispatchIterator) Close() error { +func (it *HomeHarnessDomainNotaryRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeHarnessDispatch represents a Dispatch event raised by the HomeHarness contract. -type HomeHarnessDispatch struct { - MessageHash [32]byte - LeafIndex *big.Int - DestinationAndNonce uint64 - Tips []byte - Message []byte - Raw types.Log // Blockchain specific contextual infos +// HomeHarnessDomainNotaryRemoved represents a DomainNotaryRemoved event raised by the HomeHarness contract. +type HomeHarnessDomainNotaryRemoved struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterDispatch is a free log retrieval operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// FilterDomainNotaryRemoved is a free log retrieval operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_HomeHarness *HomeHarnessFilterer) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (*HomeHarnessDispatchIterator, error) { - - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) - } - var leafIndexRule []interface{} - for _, leafIndexItem := range leafIndex { - leafIndexRule = append(leafIndexRule, leafIndexItem) - } - var destinationAndNonceRule []interface{} - for _, destinationAndNonceItem := range destinationAndNonce { - destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) - } +// Solidity: event DomainNotaryRemoved(address notary) +func (_HomeHarness *HomeHarnessFilterer) FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*HomeHarnessDomainNotaryRemovedIterator, error) { - logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "DomainNotaryRemoved") if err != nil { return nil, err } - return &HomeHarnessDispatchIterator{contract: _HomeHarness.contract, event: "Dispatch", logs: logs, sub: sub}, nil + return &HomeHarnessDomainNotaryRemovedIterator{contract: _HomeHarness.contract, event: "DomainNotaryRemoved", logs: logs, sub: sub}, nil } -// WatchDispatch is a free log subscription operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// WatchDomainNotaryRemoved is a free log subscription operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_HomeHarness *HomeHarnessFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *HomeHarnessDispatch, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (event.Subscription, error) { - - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) - } - var leafIndexRule []interface{} - for _, leafIndexItem := range leafIndex { - leafIndexRule = append(leafIndexRule, leafIndexItem) - } - var destinationAndNonceRule []interface{} - for _, destinationAndNonceItem := range destinationAndNonce { - destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) - } +// Solidity: event DomainNotaryRemoved(address notary) +func (_HomeHarness *HomeHarnessFilterer) WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *HomeHarnessDomainNotaryRemoved) (event.Subscription, error) { - logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "DomainNotaryRemoved") if err != nil { return nil, err } @@ -4545,8 +6813,8 @@ func (_HomeHarness *HomeHarnessFilterer) WatchDispatch(opts *bind.WatchOpts, sin select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeHarnessDispatch) - if err := _HomeHarness.contract.UnpackLog(event, "Dispatch", log); err != nil { + event := new(HomeHarnessDomainNotaryRemoved) + if err := _HomeHarness.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { return err } event.Raw = log @@ -4567,21 +6835,21 @@ func (_HomeHarness *HomeHarnessFilterer) WatchDispatch(opts *bind.WatchOpts, sin }), nil } -// ParseDispatch is a log parse operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// ParseDomainNotaryRemoved is a log parse operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_HomeHarness *HomeHarnessFilterer) ParseDispatch(log types.Log) (*HomeHarnessDispatch, error) { - event := new(HomeHarnessDispatch) - if err := _HomeHarness.contract.UnpackLog(event, "Dispatch", log); err != nil { +// Solidity: event DomainNotaryRemoved(address notary) +func (_HomeHarness *HomeHarnessFilterer) ParseDomainNotaryRemoved(log types.Log) (*HomeHarnessDomainNotaryRemoved, error) { + event := new(HomeHarnessDomainNotaryRemoved) + if err := _HomeHarness.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeHarnessImproperAttestationIterator is returned from FilterImproperAttestation and is used to iterate over the raw logs and unpacked data for ImproperAttestation events raised by the HomeHarness contract. -type HomeHarnessImproperAttestationIterator struct { - Event *HomeHarnessImproperAttestation // Event containing the contract specifics and raw log +// HomeHarnessGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the HomeHarness contract. +type HomeHarnessGuardAddedIterator struct { + Event *HomeHarnessGuardAdded // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4595,7 +6863,7 @@ type HomeHarnessImproperAttestationIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeHarnessImproperAttestationIterator) Next() bool { +func (it *HomeHarnessGuardAddedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4604,7 +6872,7 @@ func (it *HomeHarnessImproperAttestationIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeHarnessImproperAttestation) + it.Event = new(HomeHarnessGuardAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4619,7 +6887,7 @@ func (it *HomeHarnessImproperAttestationIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeHarnessImproperAttestation) + it.Event = new(HomeHarnessGuardAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4635,42 +6903,41 @@ func (it *HomeHarnessImproperAttestationIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeHarnessImproperAttestationIterator) Error() error { +func (it *HomeHarnessGuardAddedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeHarnessImproperAttestationIterator) Close() error { +func (it *HomeHarnessGuardAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeHarnessImproperAttestation represents a ImproperAttestation event raised by the HomeHarness contract. -type HomeHarnessImproperAttestation struct { - Updater common.Address - Attestation []byte - Raw types.Log // Blockchain specific contextual infos +// HomeHarnessGuardAdded represents a GuardAdded event raised by the HomeHarness contract. +type HomeHarnessGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_HomeHarness *HomeHarnessFilterer) FilterImproperAttestation(opts *bind.FilterOpts) (*HomeHarnessImproperAttestationIterator, error) { +// Solidity: event GuardAdded(address guard) +func (_HomeHarness *HomeHarnessFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*HomeHarnessGuardAddedIterator, error) { - logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "ImproperAttestation") + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "GuardAdded") if err != nil { return nil, err } - return &HomeHarnessImproperAttestationIterator{contract: _HomeHarness.contract, event: "ImproperAttestation", logs: logs, sub: sub}, nil + return &HomeHarnessGuardAddedIterator{contract: _HomeHarness.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// WatchImproperAttestation is a free log subscription operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_HomeHarness *HomeHarnessFilterer) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *HomeHarnessImproperAttestation) (event.Subscription, error) { +// Solidity: event GuardAdded(address guard) +func (_HomeHarness *HomeHarnessFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *HomeHarnessGuardAdded) (event.Subscription, error) { - logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "ImproperAttestation") + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "GuardAdded") if err != nil { return nil, err } @@ -4680,8 +6947,8 @@ func (_HomeHarness *HomeHarnessFilterer) WatchImproperAttestation(opts *bind.Wat select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeHarnessImproperAttestation) - if err := _HomeHarness.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { + event := new(HomeHarnessGuardAdded) + if err := _HomeHarness.contract.UnpackLog(event, "GuardAdded", log); err != nil { return err } event.Raw = log @@ -4702,21 +6969,21 @@ func (_HomeHarness *HomeHarnessFilterer) WatchImproperAttestation(opts *bind.Wat }), nil } -// ParseImproperAttestation is a log parse operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_HomeHarness *HomeHarnessFilterer) ParseImproperAttestation(log types.Log) (*HomeHarnessImproperAttestation, error) { - event := new(HomeHarnessImproperAttestation) - if err := _HomeHarness.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { +// Solidity: event GuardAdded(address guard) +func (_HomeHarness *HomeHarnessFilterer) ParseGuardAdded(log types.Log) (*HomeHarnessGuardAdded, error) { + event := new(HomeHarnessGuardAdded) + if err := _HomeHarness.contract.UnpackLog(event, "GuardAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeHarnessInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the HomeHarness contract. -type HomeHarnessInitializedIterator struct { - Event *HomeHarnessInitialized // Event containing the contract specifics and raw log +// HomeHarnessGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the HomeHarness contract. +type HomeHarnessGuardRemovedIterator struct { + Event *HomeHarnessGuardRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4730,7 +6997,7 @@ type HomeHarnessInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeHarnessInitializedIterator) Next() bool { +func (it *HomeHarnessGuardRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4739,7 +7006,7 @@ func (it *HomeHarnessInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeHarnessInitialized) + it.Event = new(HomeHarnessGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4754,7 +7021,7 @@ func (it *HomeHarnessInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeHarnessInitialized) + it.Event = new(HomeHarnessGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4770,41 +7037,41 @@ func (it *HomeHarnessInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeHarnessInitializedIterator) Error() error { +func (it *HomeHarnessGuardRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeHarnessInitializedIterator) Close() error { +func (it *HomeHarnessGuardRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeHarnessInitialized represents a Initialized event raised by the HomeHarness contract. -type HomeHarnessInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// HomeHarnessGuardRemoved represents a GuardRemoved event raised by the HomeHarness contract. +type HomeHarnessGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_HomeHarness *HomeHarnessFilterer) FilterInitialized(opts *bind.FilterOpts) (*HomeHarnessInitializedIterator, error) { +// Solidity: event GuardRemoved(address guard) +func (_HomeHarness *HomeHarnessFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*HomeHarnessGuardRemovedIterator, error) { - logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "Initialized") + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "GuardRemoved") if err != nil { return nil, err } - return &HomeHarnessInitializedIterator{contract: _HomeHarness.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &HomeHarnessGuardRemovedIterator{contract: _HomeHarness.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_HomeHarness *HomeHarnessFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *HomeHarnessInitialized) (event.Subscription, error) { +// Solidity: event GuardRemoved(address guard) +func (_HomeHarness *HomeHarnessFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *HomeHarnessGuardRemoved) (event.Subscription, error) { - logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "Initialized") + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "GuardRemoved") if err != nil { return nil, err } @@ -4814,8 +7081,8 @@ func (_HomeHarness *HomeHarnessFilterer) WatchInitialized(opts *bind.WatchOpts, select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeHarnessInitialized) - if err := _HomeHarness.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(HomeHarnessGuardRemoved) + if err := _HomeHarness.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return err } event.Raw = log @@ -4836,21 +7103,21 @@ func (_HomeHarness *HomeHarnessFilterer) WatchInitialized(opts *bind.WatchOpts, }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_HomeHarness *HomeHarnessFilterer) ParseInitialized(log types.Log) (*HomeHarnessInitialized, error) { - event := new(HomeHarnessInitialized) - if err := _HomeHarness.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event GuardRemoved(address guard) +func (_HomeHarness *HomeHarnessFilterer) ParseGuardRemoved(log types.Log) (*HomeHarnessGuardRemoved, error) { + event := new(HomeHarnessGuardRemoved) + if err := _HomeHarness.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeHarnessNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the HomeHarness contract. -type HomeHarnessNewUpdaterIterator struct { - Event *HomeHarnessNewUpdater // Event containing the contract specifics and raw log +// HomeHarnessImproperAttestationIterator is returned from FilterImproperAttestation and is used to iterate over the raw logs and unpacked data for ImproperAttestation events raised by the HomeHarness contract. +type HomeHarnessImproperAttestationIterator struct { + Event *HomeHarnessImproperAttestation // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4864,7 +7131,7 @@ type HomeHarnessNewUpdaterIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeHarnessNewUpdaterIterator) Next() bool { +func (it *HomeHarnessImproperAttestationIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4873,7 +7140,7 @@ func (it *HomeHarnessNewUpdaterIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeHarnessNewUpdater) + it.Event = new(HomeHarnessImproperAttestation) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4888,7 +7155,7 @@ func (it *HomeHarnessNewUpdaterIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeHarnessNewUpdater) + it.Event = new(HomeHarnessImproperAttestation) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4904,42 +7171,42 @@ func (it *HomeHarnessNewUpdaterIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeHarnessNewUpdaterIterator) Error() error { +func (it *HomeHarnessImproperAttestationIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeHarnessNewUpdaterIterator) Close() error { +func (it *HomeHarnessImproperAttestationIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeHarnessNewUpdater represents a NewUpdater event raised by the HomeHarness contract. -type HomeHarnessNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// HomeHarnessImproperAttestation represents a ImproperAttestation event raised by the HomeHarness contract. +type HomeHarnessImproperAttestation struct { + Updater common.Address + Attestation []byte + Raw types.Log // Blockchain specific contextual infos } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_HomeHarness *HomeHarnessFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*HomeHarnessNewUpdaterIterator, error) { +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_HomeHarness *HomeHarnessFilterer) FilterImproperAttestation(opts *bind.FilterOpts) (*HomeHarnessImproperAttestationIterator, error) { - logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "NewUpdater") + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "ImproperAttestation") if err != nil { return nil, err } - return &HomeHarnessNewUpdaterIterator{contract: _HomeHarness.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &HomeHarnessImproperAttestationIterator{contract: _HomeHarness.contract, event: "ImproperAttestation", logs: logs, sub: sub}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// WatchImproperAttestation is a free log subscription operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_HomeHarness *HomeHarnessFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *HomeHarnessNewUpdater) (event.Subscription, error) { +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_HomeHarness *HomeHarnessFilterer) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *HomeHarnessImproperAttestation) (event.Subscription, error) { - logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "NewUpdater") + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "ImproperAttestation") if err != nil { return nil, err } @@ -4949,8 +7216,8 @@ func (_HomeHarness *HomeHarnessFilterer) WatchNewUpdater(opts *bind.WatchOpts, s select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeHarnessNewUpdater) - if err := _HomeHarness.contract.UnpackLog(event, "NewUpdater", log); err != nil { + event := new(HomeHarnessImproperAttestation) + if err := _HomeHarness.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { return err } event.Raw = log @@ -4971,21 +7238,21 @@ func (_HomeHarness *HomeHarnessFilterer) WatchNewUpdater(opts *bind.WatchOpts, s }), nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// ParseImproperAttestation is a log parse operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_HomeHarness *HomeHarnessFilterer) ParseNewUpdater(log types.Log) (*HomeHarnessNewUpdater, error) { - event := new(HomeHarnessNewUpdater) - if err := _HomeHarness.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_HomeHarness *HomeHarnessFilterer) ParseImproperAttestation(log types.Log) (*HomeHarnessImproperAttestation, error) { + event := new(HomeHarnessImproperAttestation) + if err := _HomeHarness.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeHarnessNewUpdaterManagerIterator is returned from FilterNewUpdaterManager and is used to iterate over the raw logs and unpacked data for NewUpdaterManager events raised by the HomeHarness contract. -type HomeHarnessNewUpdaterManagerIterator struct { - Event *HomeHarnessNewUpdaterManager // Event containing the contract specifics and raw log +// HomeHarnessInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the HomeHarness contract. +type HomeHarnessInitializedIterator struct { + Event *HomeHarnessInitialized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4999,7 +7266,7 @@ type HomeHarnessNewUpdaterManagerIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeHarnessNewUpdaterManagerIterator) Next() bool { +func (it *HomeHarnessInitializedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -5008,7 +7275,7 @@ func (it *HomeHarnessNewUpdaterManagerIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeHarnessNewUpdaterManager) + it.Event = new(HomeHarnessInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5023,7 +7290,7 @@ func (it *HomeHarnessNewUpdaterManagerIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeHarnessNewUpdaterManager) + it.Event = new(HomeHarnessInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5039,41 +7306,41 @@ func (it *HomeHarnessNewUpdaterManagerIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeHarnessNewUpdaterManagerIterator) Error() error { +func (it *HomeHarnessInitializedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeHarnessNewUpdaterManagerIterator) Close() error { +func (it *HomeHarnessInitializedIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeHarnessNewUpdaterManager represents a NewUpdaterManager event raised by the HomeHarness contract. -type HomeHarnessNewUpdaterManager struct { - UpdaterManager common.Address - Raw types.Log // Blockchain specific contextual infos +// HomeHarnessInitialized represents a Initialized event raised by the HomeHarness contract. +type HomeHarnessInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_HomeHarness *HomeHarnessFilterer) FilterNewUpdaterManager(opts *bind.FilterOpts) (*HomeHarnessNewUpdaterManagerIterator, error) { +// Solidity: event Initialized(uint8 version) +func (_HomeHarness *HomeHarnessFilterer) FilterInitialized(opts *bind.FilterOpts) (*HomeHarnessInitializedIterator, error) { - logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "NewUpdaterManager") + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &HomeHarnessNewUpdaterManagerIterator{contract: _HomeHarness.contract, event: "NewUpdaterManager", logs: logs, sub: sub}, nil + return &HomeHarnessInitializedIterator{contract: _HomeHarness.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// WatchNewUpdaterManager is a free log subscription operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_HomeHarness *HomeHarnessFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *HomeHarnessNewUpdaterManager) (event.Subscription, error) { +// Solidity: event Initialized(uint8 version) +func (_HomeHarness *HomeHarnessFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *HomeHarnessInitialized) (event.Subscription, error) { - logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "NewUpdaterManager") + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } @@ -5083,8 +7350,8 @@ func (_HomeHarness *HomeHarnessFilterer) WatchNewUpdaterManager(opts *bind.Watch select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeHarnessNewUpdaterManager) - if err := _HomeHarness.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { + event := new(HomeHarnessInitialized) + if err := _HomeHarness.contract.UnpackLog(event, "Initialized", log); err != nil { return err } event.Raw = log @@ -5105,21 +7372,21 @@ func (_HomeHarness *HomeHarnessFilterer) WatchNewUpdaterManager(opts *bind.Watch }), nil } -// ParseNewUpdaterManager is a log parse operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_HomeHarness *HomeHarnessFilterer) ParseNewUpdaterManager(log types.Log) (*HomeHarnessNewUpdaterManager, error) { - event := new(HomeHarnessNewUpdaterManager) - if err := _HomeHarness.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { +// Solidity: event Initialized(uint8 version) +func (_HomeHarness *HomeHarnessFilterer) ParseInitialized(log types.Log) (*HomeHarnessInitialized, error) { + event := new(HomeHarnessInitialized) + if err := _HomeHarness.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeHarnessOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the HomeHarness contract. -type HomeHarnessOwnershipTransferredIterator struct { - Event *HomeHarnessOwnershipTransferred // Event containing the contract specifics and raw log +// HomeHarnessNewUpdaterManagerIterator is returned from FilterNewUpdaterManager and is used to iterate over the raw logs and unpacked data for NewUpdaterManager events raised by the HomeHarness contract. +type HomeHarnessNewUpdaterManagerIterator struct { + Event *HomeHarnessNewUpdaterManager // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -5133,7 +7400,7 @@ type HomeHarnessOwnershipTransferredIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeHarnessOwnershipTransferredIterator) Next() bool { +func (it *HomeHarnessNewUpdaterManagerIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -5142,7 +7409,7 @@ func (it *HomeHarnessOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeHarnessOwnershipTransferred) + it.Event = new(HomeHarnessNewUpdaterManager) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5157,7 +7424,7 @@ func (it *HomeHarnessOwnershipTransferredIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeHarnessOwnershipTransferred) + it.Event = new(HomeHarnessNewUpdaterManager) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5173,60 +7440,41 @@ func (it *HomeHarnessOwnershipTransferredIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeHarnessOwnershipTransferredIterator) Error() error { +func (it *HomeHarnessNewUpdaterManagerIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeHarnessOwnershipTransferredIterator) Close() error { +func (it *HomeHarnessNewUpdaterManagerIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeHarnessOwnershipTransferred represents a OwnershipTransferred event raised by the HomeHarness contract. -type HomeHarnessOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// HomeHarnessNewUpdaterManager represents a NewUpdaterManager event raised by the HomeHarness contract. +type HomeHarnessNewUpdaterManager struct { + UpdaterManager common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_HomeHarness *HomeHarnessFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*HomeHarnessOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Solidity: event NewUpdaterManager(address updaterManager) +func (_HomeHarness *HomeHarnessFilterer) FilterNewUpdaterManager(opts *bind.FilterOpts) (*HomeHarnessNewUpdaterManagerIterator, error) { - logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "NewUpdaterManager") if err != nil { return nil, err } - return &HomeHarnessOwnershipTransferredIterator{contract: _HomeHarness.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &HomeHarnessNewUpdaterManagerIterator{contract: _HomeHarness.contract, event: "NewUpdaterManager", logs: logs, sub: sub}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// WatchNewUpdaterManager is a free log subscription operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_HomeHarness *HomeHarnessFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *HomeHarnessOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Solidity: event NewUpdaterManager(address updaterManager) +func (_HomeHarness *HomeHarnessFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *HomeHarnessNewUpdaterManager) (event.Subscription, error) { - logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "NewUpdaterManager") if err != nil { return nil, err } @@ -5236,8 +7484,8 @@ func (_HomeHarness *HomeHarnessFilterer) WatchOwnershipTransferred(opts *bind.Wa select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeHarnessOwnershipTransferred) - if err := _HomeHarness.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(HomeHarnessNewUpdaterManager) + if err := _HomeHarness.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { return err } event.Raw = log @@ -5258,21 +7506,21 @@ func (_HomeHarness *HomeHarnessFilterer) WatchOwnershipTransferred(opts *bind.Wa }), nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// ParseNewUpdaterManager is a log parse operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_HomeHarness *HomeHarnessFilterer) ParseOwnershipTransferred(log types.Log) (*HomeHarnessOwnershipTransferred, error) { - event := new(HomeHarnessOwnershipTransferred) - if err := _HomeHarness.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// Solidity: event NewUpdaterManager(address updaterManager) +func (_HomeHarness *HomeHarnessFilterer) ParseNewUpdaterManager(log types.Log) (*HomeHarnessNewUpdaterManager, error) { + event := new(HomeHarnessNewUpdaterManager) + if err := _HomeHarness.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeHarnessUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the HomeHarness contract. -type HomeHarnessUpdateIterator struct { - Event *HomeHarnessUpdate // Event containing the contract specifics and raw log +// HomeHarnessOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the HomeHarness contract. +type HomeHarnessOwnershipTransferredIterator struct { + Event *HomeHarnessOwnershipTransferred // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -5286,7 +7534,7 @@ type HomeHarnessUpdateIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeHarnessUpdateIterator) Next() bool { +func (it *HomeHarnessOwnershipTransferredIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -5295,7 +7543,7 @@ func (it *HomeHarnessUpdateIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeHarnessUpdate) + it.Event = new(HomeHarnessOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5310,7 +7558,7 @@ func (it *HomeHarnessUpdateIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeHarnessUpdate) + it.Event = new(HomeHarnessOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5326,70 +7574,60 @@ func (it *HomeHarnessUpdateIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeHarnessUpdateIterator) Error() error { +func (it *HomeHarnessOwnershipTransferredIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeHarnessUpdateIterator) Close() error { +func (it *HomeHarnessOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeHarnessUpdate represents a Update event raised by the HomeHarness contract. -type HomeHarnessUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// HomeHarnessOwnershipTransferred represents a OwnershipTransferred event raised by the HomeHarness contract. +type HomeHarnessOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_HomeHarness *HomeHarnessFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*HomeHarnessUpdateIterator, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_HomeHarness *HomeHarnessFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*HomeHarnessOwnershipTransferredIterator, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _HomeHarness.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } - return &HomeHarnessUpdateIterator{contract: _HomeHarness.contract, event: "Update", logs: logs, sub: sub}, nil + return &HomeHarnessOwnershipTransferredIterator{contract: _HomeHarness.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_HomeHarness *HomeHarnessFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *HomeHarnessUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_HomeHarness *HomeHarnessFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *HomeHarnessOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _HomeHarness.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } @@ -5399,8 +7637,8 @@ func (_HomeHarness *HomeHarnessFilterer) WatchUpdate(opts *bind.WatchOpts, sink select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeHarnessUpdate) - if err := _HomeHarness.contract.UnpackLog(event, "Update", log); err != nil { + event := new(HomeHarnessOwnershipTransferred) + if err := _HomeHarness.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -5421,12 +7659,12 @@ func (_HomeHarness *HomeHarnessFilterer) WatchUpdate(opts *bind.WatchOpts, sink }), nil } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_HomeHarness *HomeHarnessFilterer) ParseUpdate(log types.Log) (*HomeHarnessUpdate, error) { - event := new(HomeHarnessUpdate) - if err := _HomeHarness.contract.UnpackLog(event, "Update", log); err != nil { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_HomeHarness *HomeHarnessFilterer) ParseOwnershipTransferred(log types.Log) (*HomeHarnessOwnershipTransferred, error) { + event := new(HomeHarnessOwnershipTransferred) + if err := _HomeHarness.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log @@ -6264,7 +8502,7 @@ func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*I // MerkleLibMetaData contains all meta data concerning the MerkleLib contract. var MerkleLibMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122071d0a88a74163b9ea5ce5f06f2b61a24f8f2f2e3594e5870172cb9f9326aa9cd64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206d5609d71b06c43aa16a5b9f4ccdd35581ddf50e9c8fba3a1397bee8c344599864736f6c634300080d0033", } // MerkleLibABI is the input ABI used to generate the binding from. @@ -6443,7 +8681,7 @@ var MerkleTreeManagerMetaData = &bind.MetaData{ "ebf0c717": "root()", "fd54b228": "tree()", }, - Bin: "0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212209c9021ddf69086cc54a59051cec9059651ff5909bff79db72268369753fd9de864736f6c634300080d0033", + Bin: "0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220dd786f68e4fb682c8db40afa31676fada6a06dcdaf6c67cd8e7b6a24d919bbce64736f6c634300080d0033", } // MerkleTreeManagerABI is the input ABI used to generate the binding from. @@ -6744,7 +8982,7 @@ func (_MerkleTreeManager *MerkleTreeManagerCallerSession) Tree() (*big.Int, erro // MessageMetaData contains all meta data concerning the Message contract. var MessageMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b92804997a3979ca0163f8a39c825c97df2a0479a80ee555b1da53d3665d89f464736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d68f867782174e52085ebd396db960afccb6427cc9b7ba9c885f7b4801f9835564736f6c634300080d0033", } // MessageABI is the input ABI used to generate the binding from. @@ -7437,7 +9675,7 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred // StringsMetaData contains all meta data concerning the Strings contract. var StringsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122096df387be66f1aee593fa1d4a2944fcece444aa43bdae2797d8be977840c119e64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c2daf27698cda67f8942012ea1b6cb47cf6738686a1bfb7586689892aa93a6bc64736f6c634300080d0033", } // StringsABI is the input ABI used to generate the binding from. @@ -7607,308 +9845,125 @@ func (_Strings *StringsTransactorRaw) Transact(opts *bind.TransactOpts, method s return _Strings.Contract.contract.Transact(opts, method, params...) } -// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. -var SystemMessageMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a8ca0e2e4502dcc04ac97920ed2e255a76ea016ce7a168b44075cf841404f8d664736f6c634300080d0033", -} - -// SystemMessageABI is the input ABI used to generate the binding from. -// Deprecated: Use SystemMessageMetaData.ABI instead. -var SystemMessageABI = SystemMessageMetaData.ABI - -// SystemMessageBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use SystemMessageMetaData.Bin instead. -var SystemMessageBin = SystemMessageMetaData.Bin - -// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. -func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { - parsed, err := SystemMessageMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil -} - -// SystemMessage is an auto generated Go binding around an Ethereum contract. -type SystemMessage struct { - SystemMessageCaller // Read-only binding to the contract - SystemMessageTransactor // Write-only binding to the contract - SystemMessageFilterer // Log filterer for contract events -} - -// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. -type SystemMessageCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type SystemMessageTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type SystemMessageFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type SystemMessageSession struct { - Contract *SystemMessage // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type SystemMessageCallerSession struct { - Contract *SystemMessageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type SystemMessageTransactorSession struct { - Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. -type SystemMessageRaw struct { - Contract *SystemMessage // Generic contract binding to access the raw methods on -} - -// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type SystemMessageCallerRaw struct { - Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on -} - -// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type SystemMessageTransactorRaw struct { - Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { - contract, err := bindSystemMessage(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil -} - -// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { - contract, err := bindSystemMessage(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &SystemMessageCaller{contract: contract}, nil -} - -// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { - contract, err := bindSystemMessage(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &SystemMessageTransactor{contract: contract}, nil -} - -// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { - contract, err := bindSystemMessage(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &SystemMessageFilterer{contract: contract}, nil -} - -// bindSystemMessage binds a generic wrapper to an already deployed contract. -func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transact(opts, method, params...) -} - -// TipsMetaData contains all meta data concerning the Tips contract. -var TipsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205e16e39e5bf3bdcd19bdd48b3dc2a33c9284abb928eaea5a5abb24607d9c057464736f6c634300080d0033", +// SystemContractMetaData contains all meta data concerning the SystemContract contract. +var SystemContractMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8d3638f4": "localDomain()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "b7bc563e": "setSystemMessenger(address)", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + }, } -// TipsABI is the input ABI used to generate the binding from. -// Deprecated: Use TipsMetaData.ABI instead. -var TipsABI = TipsMetaData.ABI - -// TipsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TipsMetaData.Bin instead. -var TipsBin = TipsMetaData.Bin - -// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. -func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { - parsed, err := TipsMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// SystemContractABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemContractMetaData.ABI instead. +var SystemContractABI = SystemContractMetaData.ABI - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil -} +// Deprecated: Use SystemContractMetaData.Sigs instead. +// SystemContractFuncSigs maps the 4-byte function signature to its string representation. +var SystemContractFuncSigs = SystemContractMetaData.Sigs -// Tips is an auto generated Go binding around an Ethereum contract. -type Tips struct { - TipsCaller // Read-only binding to the contract - TipsTransactor // Write-only binding to the contract - TipsFilterer // Log filterer for contract events +// SystemContract is an auto generated Go binding around an Ethereum contract. +type SystemContract struct { + SystemContractCaller // Read-only binding to the contract + SystemContractTransactor // Write-only binding to the contract + SystemContractFilterer // Log filterer for contract events } -// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TipsCaller struct { +// SystemContractCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemContractCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TipsTransactor struct { +// SystemContractTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemContractTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TipsFilterer struct { +// SystemContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemContractFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsSession is an auto generated Go binding around an Ethereum contract, +// SystemContractSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TipsSession struct { - Contract *Tips // Generic contract binding to set the session for +type SystemContractSession struct { + Contract *SystemContract // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TipsCallerSession struct { - Contract *TipsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemContractCallerSession struct { + Contract *SystemContractCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TipsTransactorSession struct { - Contract *TipsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemContractTransactorSession struct { + Contract *SystemContractTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TipsRaw struct { - Contract *Tips // Generic contract binding to access the raw methods on +// SystemContractRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemContractRaw struct { + Contract *SystemContract // Generic contract binding to access the raw methods on } -// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TipsCallerRaw struct { - Contract *TipsCaller // Generic read-only contract binding to access the raw methods on +// SystemContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemContractCallerRaw struct { + Contract *SystemContractCaller // Generic read-only contract binding to access the raw methods on } -// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TipsTransactorRaw struct { - Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on +// SystemContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemContractTransactorRaw struct { + Contract *SystemContractTransactor // Generic write-only contract binding to access the raw methods on } -// NewTips creates a new instance of Tips, bound to a specific deployed contract. -func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { - contract, err := bindTips(address, backend, backend, backend) +// NewSystemContract creates a new instance of SystemContract, bound to a specific deployed contract. +func NewSystemContract(address common.Address, backend bind.ContractBackend) (*SystemContract, error) { + contract, err := bindSystemContract(address, backend, backend, backend) if err != nil { return nil, err } - return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil + return &SystemContract{SystemContractCaller: SystemContractCaller{contract: contract}, SystemContractTransactor: SystemContractTransactor{contract: contract}, SystemContractFilterer: SystemContractFilterer{contract: contract}}, nil } -// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. -func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { - contract, err := bindTips(address, caller, nil, nil) +// NewSystemContractCaller creates a new read-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractCaller(address common.Address, caller bind.ContractCaller) (*SystemContractCaller, error) { + contract, err := bindSystemContract(address, caller, nil, nil) if err != nil { return nil, err } - return &TipsCaller{contract: contract}, nil + return &SystemContractCaller{contract: contract}, nil } -// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. -func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { - contract, err := bindTips(address, nil, transactor, nil) +// NewSystemContractTransactor creates a new write-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemContractTransactor, error) { + contract, err := bindSystemContract(address, nil, transactor, nil) if err != nil { return nil, err } - return &TipsTransactor{contract: contract}, nil + return &SystemContractTransactor{contract: contract}, nil } -// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. -func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { - contract, err := bindTips(address, nil, nil, filterer) +// NewSystemContractFilterer creates a new log filterer instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemContractFilterer, error) { + contract, err := bindSystemContract(address, nil, nil, filterer) if err != nil { return nil, err } - return &TipsFilterer{contract: contract}, nil + return &SystemContractFilterer{contract: contract}, nil } -// bindTips binds a generic wrapper to an already deployed contract. -func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TipsABI)) +// bindSystemContract binds a generic wrapper to an already deployed contract. +func bindSystemContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemContractABI)) if err != nil { return nil, err } @@ -7919,237 +9974,500 @@ func bindTips(address common.Address, caller bind.ContractCaller, transactor bin // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.SystemContractCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transfer(opts) +func (_SystemContract *SystemContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.contract.Transfer(opts) +func (_SystemContract *SystemContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transact(opts, method, params...) } -// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. -var TypeCastsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b6637fa98ecec80322327ba00ad3111d21cd8cd0bb6f3c2a6a53db8478296cb464736f6c634300080d0033", +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// TypeCastsABI is the input ABI used to generate the binding from. -// Deprecated: Use TypeCastsMetaData.ABI instead. -var TypeCastsABI = TypeCastsMetaData.ABI +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} -// TypeCastsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypeCastsMetaData.Bin instead. -var TypeCastsBin = TypeCastsMetaData.Bin +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCallerSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "owner") -// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. -func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { - parsed, err := TypeCastsMetaData.GetAbi() if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + return *new(common.Address), err } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCallerSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "systemMessenger") + if err != nil { - return common.Address{}, nil, nil, err + return *new(common.Address), err } - return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// TypeCasts is an auto generated Go binding around an Ethereum contract. -type TypeCasts struct { - TypeCastsCaller // Read-only binding to the contract - TypeCastsTransactor // Write-only binding to the contract - TypeCastsFilterer // Log filterer for contract events +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypeCastsCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCallerSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypeCastsTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "renounceOwnership") } -// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypeCastsFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) } -// TypeCastsSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type TypeCastsSession struct { - Contract *TypeCasts // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// SystemContractInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the SystemContract contract. +type SystemContractInitializedIterator struct { + Event *SystemContractInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type TypeCastsCallerSession struct { - Contract *TypeCastsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type TypeCastsTransactorSession struct { - Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypeCastsRaw struct { - Contract *TypeCasts // Generic contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractInitializedIterator) Error() error { + return it.fail } -// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypeCastsCallerRaw struct { - Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypeCastsTransactorRaw struct { - Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on +// SystemContractInitialized represents a Initialized event raised by the SystemContract contract. +type SystemContractInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { - contract, err := bindTypeCasts(address, backend, backend, backend) +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) FilterInitialized(opts *bind.FilterOpts) (*SystemContractInitializedIterator, error) { + + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + return &SystemContractInitializedIterator{contract: _SystemContract.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { - contract, err := bindTypeCasts(address, caller, nil, nil) +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *SystemContractInitialized) (event.Subscription, error) { + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypeCastsCaller{contract: contract}, nil + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { - contract, err := bindTypeCasts(address, nil, transactor, nil) - if err != nil { +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) ParseInitialized(log types.Log) (*SystemContractInitialized, error) { + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } - return &TypeCastsTransactor{contract: contract}, nil + event.Raw = log + return event, nil } -// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { - contract, err := bindTypeCasts(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &TypeCastsFilterer{contract: contract}, nil +// SystemContractOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the SystemContract contract. +type SystemContractOwnershipTransferredIterator struct { + Event *SystemContractOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// bindTypeCasts binds a generic wrapper to an already deployed contract. -func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) - if err != nil { - return nil, err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractOwnershipTransferredIterator) Error() error { + return it.fail } -// Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.contract.Call(opts, result, method, params...) +// SystemContractOwnershipTransferred represents a OwnershipTransferred event raised by the SystemContract contract. +type SystemContractOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transfer(opts) +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*SystemContractOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &SystemContractOwnershipTransferredIterator{contract: _SystemContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transact(opts, method, params...) +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *SystemContractOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. -var TypedMemViewMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "f26be3fc": "NULL()", - }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220bbfff1ea24e5e547b993f738b9bbc5e55455507a78805fb3d41437f8386bb22d64736f6c634300080d0033", +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) ParseOwnershipTransferred(log types.Log) (*SystemContractOwnershipTransferred, error) { + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// TypedMemViewABI is the input ABI used to generate the binding from. -// Deprecated: Use TypedMemViewMetaData.ABI instead. -var TypedMemViewABI = TypedMemViewMetaData.ABI +// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. +var SystemMessageMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122080b95c0a0564447278f1ba8189c6635d1faab45a84ab1d3d8d8eab479497d47f64736f6c634300080d0033", +} -// Deprecated: Use TypedMemViewMetaData.Sigs instead. -// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. -var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs +// SystemMessageABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemMessageMetaData.ABI instead. +var SystemMessageABI = SystemMessageMetaData.ABI -// TypedMemViewBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypedMemViewMetaData.Bin instead. -var TypedMemViewBin = TypedMemViewMetaData.Bin +// SystemMessageBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SystemMessageMetaData.Bin instead. +var SystemMessageBin = SystemMessageMetaData.Bin -// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. -func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { - parsed, err := TypedMemViewMetaData.GetAbi() +// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. +func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { + parsed, err := SystemMessageMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -8157,111 +10475,111 @@ func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) ( return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// TypedMemView is an auto generated Go binding around an Ethereum contract. -type TypedMemView struct { - TypedMemViewCaller // Read-only binding to the contract - TypedMemViewTransactor // Write-only binding to the contract - TypedMemViewFilterer // Log filterer for contract events +// SystemMessage is an auto generated Go binding around an Ethereum contract. +type SystemMessage struct { + SystemMessageCaller // Read-only binding to the contract + SystemMessageTransactor // Write-only binding to the contract + SystemMessageFilterer // Log filterer for contract events } -// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypedMemViewCaller struct { +// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemMessageCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypedMemViewTransactor struct { +// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemMessageTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypedMemViewFilterer struct { +// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemMessageFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// SystemMessageSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TypedMemViewSession struct { - Contract *TypedMemView // Generic contract binding to set the session for +type SystemMessageSession struct { + Contract *SystemMessage // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TypedMemViewCallerSession struct { - Contract *TypedMemViewCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemMessageCallerSession struct { + Contract *SystemMessageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TypedMemViewTransactorSession struct { - Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemMessageTransactorSession struct { + Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypedMemViewRaw struct { - Contract *TypedMemView // Generic contract binding to access the raw methods on +// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemMessageRaw struct { + Contract *SystemMessage // Generic contract binding to access the raw methods on } -// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypedMemViewCallerRaw struct { - Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on +// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemMessageCallerRaw struct { + Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on } -// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypedMemViewTransactorRaw struct { - Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on +// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemMessageTransactorRaw struct { + Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on } -// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { - contract, err := bindTypedMemView(address, backend, backend, backend) +// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { + contract, err := bindSystemMessage(address, backend, backend, backend) if err != nil { return nil, err } - return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { - contract, err := bindTypedMemView(address, caller, nil, nil) +// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { + contract, err := bindSystemMessage(address, caller, nil, nil) if err != nil { return nil, err } - return &TypedMemViewCaller{contract: contract}, nil + return &SystemMessageCaller{contract: contract}, nil } -// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { - contract, err := bindTypedMemView(address, nil, transactor, nil) +// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { + contract, err := bindSystemMessage(address, nil, transactor, nil) if err != nil { return nil, err } - return &TypedMemViewTransactor{contract: contract}, nil + return &SystemMessageTransactor{contract: contract}, nil } -// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { - contract, err := bindTypedMemView(address, nil, nil, filterer) +// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { + contract, err := bindSystemMessage(address, nil, nil, filterer) if err != nil { return nil, err } - return &TypedMemViewFilterer{contract: contract}, nil + return &SystemMessageFilterer{contract: contract}, nil } -// bindTypedMemView binds a generic wrapper to an already deployed contract. -func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) +// bindSystemMessage binds a generic wrapper to an already deployed contract. +func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) if err != nil { return nil, err } @@ -8272,191 +10590,169 @@ func bindTypedMemView(address common.Address, caller bind.ContractCaller, transa // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) +func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transfer(opts) +func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transact(opts, method, params...) -} - -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { - var out []interface{} - err := _TypedMemView.contract.Call(opts, &out, "NULL") - - if err != nil { - return *new([29]byte), err - } - - out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - - return out0, err - +func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transact(opts, method, params...) } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) +// TipsMetaData contains all meta data concerning the Tips contract. +var TipsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122074a959b828fde41e1156b006f04e5949b364bf55e9b52b7f0a505b0b6ec1084464736f6c634300080d0033", } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) -} +// TipsABI is the input ABI used to generate the binding from. +// Deprecated: Use TipsMetaData.ABI instead. +var TipsABI = TipsMetaData.ABI -// UpdaterStorageMetaData contains all meta data concerning the UpdaterStorage contract. -var UpdaterStorageMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "8d3638f4": "localDomain()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "b7bc563e": "setSystemMessenger(address)", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "df034cd0": "updater()", - }, -} +// TipsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TipsMetaData.Bin instead. +var TipsBin = TipsMetaData.Bin -// UpdaterStorageABI is the input ABI used to generate the binding from. -// Deprecated: Use UpdaterStorageMetaData.ABI instead. -var UpdaterStorageABI = UpdaterStorageMetaData.ABI +// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. +func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { + parsed, err := TipsMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } -// Deprecated: Use UpdaterStorageMetaData.Sigs instead. -// UpdaterStorageFuncSigs maps the 4-byte function signature to its string representation. -var UpdaterStorageFuncSigs = UpdaterStorageMetaData.Sigs + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil +} -// UpdaterStorage is an auto generated Go binding around an Ethereum contract. -type UpdaterStorage struct { - UpdaterStorageCaller // Read-only binding to the contract - UpdaterStorageTransactor // Write-only binding to the contract - UpdaterStorageFilterer // Log filterer for contract events +// Tips is an auto generated Go binding around an Ethereum contract. +type Tips struct { + TipsCaller // Read-only binding to the contract + TipsTransactor // Write-only binding to the contract + TipsFilterer // Log filterer for contract events } -// UpdaterStorageCaller is an auto generated read-only Go binding around an Ethereum contract. -type UpdaterStorageCaller struct { +// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TipsCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactor struct { +// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TipsTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UpdaterStorageFilterer struct { +// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TipsFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageSession is an auto generated Go binding around an Ethereum contract, +// TipsSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type UpdaterStorageSession struct { - Contract *UpdaterStorage // Generic contract binding to set the session for +type TipsSession struct { + Contract *Tips // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type UpdaterStorageCallerSession struct { - Contract *UpdaterStorageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type TipsCallerSession struct { + Contract *TipsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// UpdaterStorageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type UpdaterStorageTransactorSession struct { - Contract *UpdaterStorageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type TipsTransactorSession struct { + Contract *TipsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageRaw is an auto generated low-level Go binding around an Ethereum contract. -type UpdaterStorageRaw struct { - Contract *UpdaterStorage // Generic contract binding to access the raw methods on +// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TipsRaw struct { + Contract *Tips // Generic contract binding to access the raw methods on } -// UpdaterStorageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UpdaterStorageCallerRaw struct { - Contract *UpdaterStorageCaller // Generic read-only contract binding to access the raw methods on +// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TipsCallerRaw struct { + Contract *TipsCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactorRaw struct { - Contract *UpdaterStorageTransactor // Generic write-only contract binding to access the raw methods on +// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TipsTransactorRaw struct { + Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on } -// NewUpdaterStorage creates a new instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorage(address common.Address, backend bind.ContractBackend) (*UpdaterStorage, error) { - contract, err := bindUpdaterStorage(address, backend, backend, backend) +// NewTips creates a new instance of Tips, bound to a specific deployed contract. +func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { + contract, err := bindTips(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorage{UpdaterStorageCaller: UpdaterStorageCaller{contract: contract}, UpdaterStorageTransactor: UpdaterStorageTransactor{contract: contract}, UpdaterStorageFilterer: UpdaterStorageFilterer{contract: contract}}, nil + return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil } -// NewUpdaterStorageCaller creates a new read-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageCaller(address common.Address, caller bind.ContractCaller) (*UpdaterStorageCaller, error) { - contract, err := bindUpdaterStorage(address, caller, nil, nil) +// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. +func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { + contract, err := bindTips(address, caller, nil, nil) if err != nil { return nil, err } - return &UpdaterStorageCaller{contract: contract}, nil + return &TipsCaller{contract: contract}, nil } -// NewUpdaterStorageTransactor creates a new write-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageTransactor(address common.Address, transactor bind.ContractTransactor) (*UpdaterStorageTransactor, error) { - contract, err := bindUpdaterStorage(address, nil, transactor, nil) +// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. +func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { + contract, err := bindTips(address, nil, transactor, nil) if err != nil { return nil, err } - return &UpdaterStorageTransactor{contract: contract}, nil + return &TipsTransactor{contract: contract}, nil } -// NewUpdaterStorageFilterer creates a new log filterer instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageFilterer(address common.Address, filterer bind.ContractFilterer) (*UpdaterStorageFilterer, error) { - contract, err := bindUpdaterStorage(address, nil, nil, filterer) +// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. +func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { + contract, err := bindTips(address, nil, nil, filterer) if err != nil { return nil, err } - return &UpdaterStorageFilterer{contract: contract}, nil + return &TipsFilterer{contract: contract}, nil } -// bindUpdaterStorage binds a generic wrapper to an already deployed contract. -func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(UpdaterStorageABI)) +// bindTips binds a generic wrapper to an already deployed contract. +func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TipsABI)) if err != nil { return nil, err } @@ -8467,810 +10763,422 @@ func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.UpdaterStorageCaller.contract.Call(opts, result, method, params...) +func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transfer(opts) +func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transact(opts, method, params...) +func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.contract.Call(opts, result, method, params...) +func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transfer(opts) +func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transact(opts, method, params...) -} - -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "localDomain") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - +func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.contract.Transact(opts, method, params...) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) +// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. +var TypeCastsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200ece21e0761541fc44028f3225a340af1d1814445da8301c2e67d7d05bd194b064736f6c634300080d0033", } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCallerSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) -} +// TypeCastsABI is the input ABI used to generate the binding from. +// Deprecated: Use TypeCastsMetaData.ABI instead. +var TypeCastsABI = TypeCastsMetaData.ABI -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "owner") +// TypeCastsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypeCastsMetaData.Bin instead. +var TypeCastsBin = TypeCastsMetaData.Bin +// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. +func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { + parsed, err := TypeCastsMetaData.GetAbi() if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "systemMessenger") - - if err != nil { - return *new(common.Address), err + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "updater") - + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "setSystemMessenger", _systemMessenger) + return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// TypeCasts is an auto generated Go binding around an Ethereum contract. +type TypeCasts struct { + TypeCastsCaller // Read-only binding to the contract + TypeCastsTransactor // Write-only binding to the contract + TypeCastsFilterer // Log filterer for contract events } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypeCastsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "transferOwnership", newOwner) +// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypeCastsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypeCastsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +// TypeCastsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypeCastsSession struct { + Contract *TypeCasts // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the UpdaterStorage contract. -type UpdaterStorageInitializedIterator struct { - Event *UpdaterStorageInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypeCastsCallerSession struct { + Contract *TypeCastsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypeCastsTransactorSession struct { + Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageInitializedIterator) Error() error { - return it.fail +// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypeCastsRaw struct { + Contract *TypeCasts // Generic contract binding to access the raw methods on } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil +// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypeCastsCallerRaw struct { + Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageInitialized represents a Initialized event raised by the UpdaterStorage contract. -type UpdaterStorageInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypeCastsTransactorRaw struct { + Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterInitialized(opts *bind.FilterOpts) (*UpdaterStorageInitializedIterator, error) { - - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Initialized") +// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { + contract, err := bindTypeCasts(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorageInitializedIterator{contract: _UpdaterStorage.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *UpdaterStorageInitialized) (event.Subscription, error) { - - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Initialized") +// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { + contract, err := bindTypeCasts(address, caller, nil, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypeCastsCaller{contract: contract}, nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseInitialized(log types.Log) (*UpdaterStorageInitialized, error) { - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { +// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { + contract, err := bindTypeCasts(address, nil, transactor, nil) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &TypeCastsTransactor{contract: contract}, nil } -// UpdaterStorageNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdaterIterator struct { - Event *UpdaterStorageNewUpdater // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { + contract, err := bindTypeCasts(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TypeCastsFilterer{contract: contract}, nil } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// bindTypeCasts binds a generic wrapper to an already deployed contract. +func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) + if err != nil { + return nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageNewUpdaterIterator) Error() error { - return it.fail +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.contract.Call(opts, result, method, params...) } -// UpdaterStorageNewUpdater represents a NewUpdater event raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transfer(opts) } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*UpdaterStorageNewUpdaterIterator, error) { +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transact(opts, method, params...) +} - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "NewUpdater") - if err != nil { - return nil, err - } - return &UpdaterStorageNewUpdaterIterator{contract: _UpdaterStorage.contract, event: "NewUpdater", logs: logs, sub: sub}, nil +// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. +var TypedMemViewMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "f26be3fc": "NULL()", + }, + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220c950e5227828b3b0abe565b02888b07c56b560dc60dee268c094224f6636a2ab64736f6c634300080d0033", } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *UpdaterStorageNewUpdater) (event.Subscription, error) { +// TypedMemViewABI is the input ABI used to generate the binding from. +// Deprecated: Use TypedMemViewMetaData.ABI instead. +var TypedMemViewABI = TypedMemViewMetaData.ABI + +// Deprecated: Use TypedMemViewMetaData.Sigs instead. +// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. +var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs + +// TypedMemViewBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypedMemViewMetaData.Bin instead. +var TypedMemViewBin = TypedMemViewMetaData.Bin - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "NewUpdater") +// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. +func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { + parsed, err := TypedMemViewMetaData.GetAbi() if err != nil { - return nil, err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseNewUpdater(log types.Log) (*UpdaterStorageNewUpdater, error) { - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return nil, err + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } - event.Raw = log - return event, nil + return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil } -// UpdaterStorageOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferredIterator struct { - Event *UpdaterStorageOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// TypedMemView is an auto generated Go binding around an Ethereum contract. +type TypedMemView struct { + TypedMemViewCaller // Read-only binding to the contract + TypedMemViewTransactor // Write-only binding to the contract + TypedMemViewFilterer // Log filterer for contract events +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypedMemViewCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypedMemViewTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypedMemViewFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypedMemViewSession struct { + Contract *TypedMemView // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageOwnershipTransferredIterator) Error() error { - return it.fail +// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypedMemViewCallerSession struct { + Contract *TypedMemViewCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil +// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypedMemViewTransactorSession struct { + Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageOwnershipTransferred represents a OwnershipTransferred event raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypedMemViewRaw struct { + Contract *TypedMemView // Generic contract binding to access the raw methods on } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UpdaterStorageOwnershipTransferredIterator, error) { +// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypedMemViewCallerRaw struct { + Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on +} - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypedMemViewTransactorRaw struct { + Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on +} - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { + contract, err := bindTypedMemView(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorageOwnershipTransferredIterator{contract: _UpdaterStorage.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UpdaterStorageOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) +// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { + contract, err := bindTypedMemView(address, caller, nil, nil) + if err != nil { + return nil, err } + return &TypedMemViewCaller{contract: contract}, nil +} - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { + contract, err := bindTypedMemView(address, nil, transactor, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypedMemViewTransactor{contract: contract}, nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseOwnershipTransferred(log types.Log) (*UpdaterStorageOwnershipTransferred, error) { - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { + contract, err := bindTypedMemView(address, nil, nil, filterer) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &TypedMemViewFilterer{contract: contract}, nil } -// UpdaterStorageUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the UpdaterStorage contract. -type UpdaterStorageUpdateIterator struct { - Event *UpdaterStorageUpdate // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// bindTypedMemView binds a generic wrapper to an already deployed contract. +func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageUpdateIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageUpdateIterator) Error() error { - return it.fail +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.contract.Call(opts, result, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageUpdateIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transfer(opts) } -// UpdaterStorageUpdate represents a Update event raised by the UpdaterStorage contract. -type UpdaterStorageUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transact(opts, method, params...) } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*UpdaterStorageUpdateIterator, error) { - - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { + var out []interface{} + err := _TypedMemView.contract.Call(opts, &out, "NULL") - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new([29]byte), err } - return &UpdaterStorageUpdateIterator{contract: _UpdaterStorage.contract, event: "Update", logs: logs, sub: sub}, nil -} -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. -// -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *UpdaterStorageUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { + out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } + return out0, err - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { - return err - } - event.Raw = log +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. +// +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseUpdate(log types.Log) (*UpdaterStorageUpdate, error) { - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } // Version0MetaData contains all meta data concerning the Version0 contract. @@ -9279,7 +11187,7 @@ var Version0MetaData = &bind.MetaData{ Sigs: map[string]string{ "ffa1ad74": "VERSION()", }, - Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220b9944c73813595f42d27e476ff6f6e703875b299e30d8f60dc86162bbe90001b64736f6c634300080d0033", + Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208f8ad3211e3115f9b258019af793e66290cedc1a3aded054194bdf54b63a012964736f6c634300080d0033", } // Version0ABI is the input ABI used to generate the binding from. diff --git a/core/contracts/test/homeharness/homeharness.contractinfo.json b/core/contracts/test/homeharness/homeharness.contractinfo.json index 33fb8183b4..e2d437ea19 100644 --- a/core/contracts/test/homeharness/homeharness.contractinfo.json +++ b/core/contracts/test/homeharness/homeharness.contractinfo.json @@ -1 +1 @@ -{"solidity/HomeHarness.sol:Address":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e0cc99aae109d4df65d4cbc28dd41a17f7335edda441f23fa32e78baab88f12e64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e0cc99aae109d4df65d4cbc28dd41a17f7335edda441f23fa32e78baab88f12e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"96866:8061:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;96866:8061:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"96866:8061:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Address\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202c6b8e1822db4f974554f11034b0edec9db33a49b7b0cacc647a148f2a41a06064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202c6b8e1822db4f974554f11034b0edec9db33a49b7b0cacc647a148f2a41a06064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"53527:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;53527:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"53527:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220328148d376d8cd36305b90ccf18e8a52a8c3b2a30f5fff8ffe0f89b95a576e3d64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220328148d376d8cd36305b90ccf18e8a52a8c3b2a30f5fff8ffe0f89b95a576e3d64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"73027:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;73027:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"73027:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122086acd960f5c044bc13d8b36301c8528c2a97255c30db32c7c759d4b3673074f064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122086acd960f5c044bc13d8b36301c8528c2a97255c30db32c7c759d4b3673074f064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"76245:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;76245:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"76245:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:AuthManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"AuthManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220dbd3805c30444ef20f50d292bc1633f9c304334441b3f8fb7dbe952cf4be342964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220dbd3805c30444ef20f50d292bc1633f9c304334441b3f8fb7dbe952cf4be342964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44461:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;44461:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"44461:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202a97cb42977a631ee079605c884e050c7f4591a2244ba2a70bc54d437d5ac88664736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202a97cb42977a631ee079605c884e050c7f4591a2244ba2a70bc54d437d5ac88664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"39177:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;39177:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"39177:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Home":{"code":"0x60a06040523480156200001157600080fd5b50604051620036d9380380620036d9833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b60805161363d6200009c6000396000818161025e01528181610d9c01526117a3015261363d6000f3fe6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220f643bf9e6b98bca92cef57a0e66845240591081bb4bd1964fd1a0fae6855bcdb64736f6c634300080d0033","runtime-code":"0x6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220f643bf9e6b98bca92cef57a0e66845240591081bb4bd1964fd1a0fae6855bcdb64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"104929:12592:0:-:0;;;107959:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71588:26;;;;104929:12592;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;104929:12592:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"104929:12592:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96350:81;;;;;;;;;;-1:-1:-1;96414:10:0;;96350:81;;;160:25:1;;;148:2;133:18;96350:81:0;;;;;;;;113758:776;;;;;;;;;;-1:-1:-1;113758:776:0;;;;;:::i;:::-;;:::i;:::-;;;1657:14:1;;1650:22;1632:41;;1620:2;1605:18;113758:776:0;1492:187:1;112207:257:0;;;;;;;;;;;;;:::i;:::-;;;;1886:10:1;1874:23;;;1856:42;;1929:2;1914:18;;1907:34;;;;1829:18;112207:257:0;1684:263:1;105811:58:0;;;;;;;;;;;;105860:9;105811:58;;72939:84;;;;;;;;;;;;;:::i;:::-;;95894:32;;;;;;;;;;-1:-1:-1;95894:32:0;;;;;:::i;:::-;;:::i;70386:35::-;;;;;;;;;;;;;;;;;;2493:10:1;2481:23;;;2463:42;;2451:2;2436:18;70386:35:0;2319:192:1;68483:85:0;;;;;;;;;;-1:-1:-1;68555:6:0;;;;68483:85;;;2692:42:1;2680:55;;;2662:74;;2650:2;2635:18;68483:85:0;2516:226:1;109848:140:0;;;;;;;;;;-1:-1:-1;109848:140:0;;;;;:::i;:::-;;:::i;109209:220::-;;;;;;;;;;-1:-1:-1;109209:220:0;;;;;:::i;:::-;;:::i;106084:37::-;;;;;;;;;;-1:-1:-1;106084:37:0;;;;;;;;;;;105988:19;;;;;;;;;;-1:-1:-1;105988:19:0;;;;;;;;72137:133;;;;;;;;;;-1:-1:-1;72137:133:0;;;;;:::i;:::-;;:::i;106160:19::-;;;;;;;;;;-1:-1:-1;106160:19:0;;;;;;;;;;;;;;;;;;:::i;108115:394::-;;;;;;;;;;-1:-1:-1;108115:394:0;;;;;:::i;:::-;;:::i;70541:39::-;;;;;;;;;;-1:-1:-1;70541:39:0;;;;;;;;70512:22;;;;;;;;;;-1:-1:-1;70512:22:0;;;;;;;;96166:81;;;;;;;;;;;;;:::i;69365:198::-;;;;;;;;;;-1:-1:-1;69365:198:0;;;;;:::i;:::-;;:::i;110494:1473::-;;;;;;:::i;:::-;;:::i;95862:26::-;;;;;;;;;;-1:-1:-1;95862:26:0;;;;;;50:33;;;;;;;;;;;;82:1;50:33;;;;;5906:4:1;5894:17;;;5876:36;;5864:2;5849:18;50:33:0;5734:184:1;113758:776:0;113840:4;108927:13;108918:5;;;;;;;:22;;;;;;;;:::i;:::-;;108910:47;;;;-1:-1:-1;;;108910:47:0;;6125:2:1;108910:47:0;;;6107:21:1;6164:2;6144:18;;;6137:30;6203:14;6183:18;;;6176:42;6235:18;;108910:47:0;;;;;;;;;113911:16:::1;113929:13:::0;113946:31:::1;113964:12;113946:17;:31::i;:::-;113910:67;;;;113987:13;114003:24;:5;:22;;;;:24::i;:::-;113987:40:::0;-1:-1:-1;114037:13:0::1;114053:23;-1:-1:-1::0;;114053:21:0;::::1;;:23::i;:::-;114161:15;:22:::0;114037:39;;-1:-1:-1;114152:31:0::1;::::0;::::1;;114148:284;;;114212:15;114228:6;114212:23;;;;;;;;;;:::i;:::-;;;;;;;;;114203:5;:32:::0;114199:139:::1;;-1:-1:-1::0;114318:5:0::1;::::0;113758:776;-1:-1:-1;;;;;113758:776:0:o;114199:139::-:1;114441:7;:5;:7::i;:::-;114463:43;114483:8;114493:12;114463:43;;;;;;;:::i;:::-;;;;;;;;114523:4;114516:11;;;;;;108967:1;113758:776:::0;;;:::o;112207:257::-;112312:15;:22;112255:13;;;;112348:11;;112344:114;;112391:10;112400:1;112391:6;:10;:::i;:::-;112375:27;;112424:15;112440:6;112424:23;;;;;;;;;;:::i;:::-;;;;;;;;;112416:31;;112344:114;112285:179;112207:257;;:::o;72939:84::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;7900:2:1;68687:68:0;;;7882:21:1;;;7919:18;;;7912:30;7978:34;7958:18;;;7951:62;8030:18;;68687:68:0;7698:356:1;68687:68:0;72939:84::o;95894:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;95894:32:0;:::o;109848:140::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;7900:2:1;68687:68:0;;;7882:21:1;;;7919:18;;;7912:30;7978:34;7958:18;;;7951:62;8030:18;;68687:68:0;7698:356:1;68687:68:0;109929:52:::1;109964:15;109929:18;:52::i;:::-;109848:140:::0;:::o;109209:220::-;108723:14;;;;;;;108701:10;:37;108693:65;;;;-1:-1:-1;;;108693:65:0;;8261:2:1;108693:65:0;;;8243:21:1;8300:2;8280:18;;;8273:30;8339:17;8319:18;;;8312:45;8374:18;;108693:65:0;8059:339:1;108693:65:0;109285:21:::1;109297:8;109285:11;:21::i;:::-;-1:-1:-1::0;109401:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;109209:220::o;72137:133::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;7900:2:1;68687:68:0;;;7882:21:1;;;7919:18;;;7912:30;7978:34;7958:18;;;7951:62;8030:18;;68687:68:0;7698:356:1;68687:68:0;72229:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;72137:133::o;108115:394::-;61379:19;61401:25;61424:1;61401:22;:25::i;:::-;61379:47;;61440:14;61436:65;;;61470:13;:20;;;;;;;;61436:65;108262:35:::1;108281:15;108262:18;:35::i;:::-;108307:50;108332:14;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108307;:50::i;:::-;108367:5;:21:::0;;;::::1;::::0;::::1;::::0;;108469:15:::1;:33:::0;;-1:-1:-1;108469:33:0;::::1;::::0;;-1:-1:-1;108469:33:0;;;;::::1;::::0;61521:99;;;;61555:13;:21;;;;;;61595:14;;-1:-1:-1;5876:36:1;;61595:14:0;;5864:2:1;5849:18;61595:14:0;;;;;;;;61521:99;61369:257;108115:394;:::o;96166:81::-;96203:7;96229:11;:4;:9;:11::i;:::-;96222:18;;96166:81;:::o;69365:198::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;7900:2:1;68687:68:0;;;7882:21:1;;;7919:18;;;7912:30;7978:34;7958:18;;;7951:62;8030:18;;68687:68:0;7698:356:1;68687:68:0;69453:22:::1;::::0;::::1;69445:73;;;::::0;-1:-1:-1;;;69445:73:0;;9060:2:1;69445:73:0::1;::::0;::::1;9042:21:1::0;9099:2;9079:18;;;9072:30;9138:34;9118:18;;;9111:62;9209:8;9189:18;;;9182:36;9235:19;;69445:73:0::1;8858:402:1::0;69445:73:0::1;69528:28;69547:8;69528:18;:28::i;110494:1473::-:0;108927:13;108918:5;;;;;;;:22;;;;;;;;:::i;:::-;;108910:47;;;;-1:-1:-1;;;108910:47:0;;6125:2:1;108910:47:0;;;6107:21:1;6164:2;6144:18;;;6137:30;6203:14;6183:18;;;6176:42;6235:18;;108910:47:0;5923:336:1;108910:47:0;105860:9:::1;110731:12;:19;:45;;110723:70;;;::::0;-1:-1:-1;;;110723:70:0;;9467:2:1;110723:70:0::1;::::0;::::1;9449:21:1::0;9506:2;9486:18;;;9479:30;9545:14;9525:18;;;9518:42;9577:18;;110723:70:0::1;9265:336:1::0;110723:70:0::1;110843:9;110811:28;:16;:5;:14;:16::i;:::-;-1:-1:-1::0;;110811:26:0::1;;:28::i;:::-;:41;;;110803:59;;;::::0;-1:-1:-1;;;110803:59:0;;9808:2:1;110803:59:0::1;::::0;::::1;9790:21:1::0;9847:1;9827:18;;;9820:29;9885:7;9865:18;;;9858:35;9910:18;;110803:59:0::1;9606:328:1::0;110803:59:0::1;110956:5;::::0;:9:::1;::::0;:5:::1;;::::0;:9:::1;:::i;:::-;110948:5;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;110993:41:0::1;111016:17:::0;110993:22:::1;:41::i;:::-;111194:5;::::0;40462:242;;;13565:16:1;40462:242:0;;;13549:102:1;13670:66;111148:11:0::1;13773:3:1::0;13769:16;;;13765:25;;13752:11;;;13745:46;13807:11;;;13800:27;;;13861:16;;;;;13843:12;;;13836:47;13917:16;;;13913:25;;13899:12;;;13892:47;13955:12;;;13948:28;;;14010:16;;;;14006:25;;;13992:12;;;13985:47;40462:242:0;;;;;;;;;14048:12:1;;;;40462:242:0;;110975:59;;-1:-1:-1;111362:21:0::1;111386:51;111408:7;111417:5;111424:12;111386:21;:51::i;:::-;111528:19:::0;;::::1;::::0;::::1;::::0;111362:75;;-1:-1:-1;111610:25:0::1;111528:19:::0;111610:11:::1;:25::i;:::-;111903:5;::::0;::::1;;115910:2:::0;115886:26;;;;;115885:37;111789:171:::1;;111847:1;111837:7;96414:10:::0;;;96350:81;111837:7:::1;:11;;;;:::i;:::-;111811:12;111789:171;111923:5;111942:8;111789:171;;;;;;;:::i;:::-;;;;;;;;110713:1254;;;;110494:1473:::0;;;;;:::o;79047:474::-;79148:16;;79203:19;:12;79148:16;79203;:19::i;:::-;79195:27;-1:-1:-1;73720:2:0;3488:26;17310:2;17306:16;;;17302:28;74974:37;79232:52;;;;-1:-1:-1;;;79232:52:0;;10756:2:1;79232:52:0;;;10738:21:1;10795:2;10775:18;;;10768:30;10834:20;10814:18;;;10807:48;10872:18;;79232:52:0;10554:342:1;79232:52:0;79305:115;79337:23;-1:-1:-1;;79337:21:0;;;:23::i;:::-;79374:36;:28;-1:-1:-1;;79374:26:0;;;:28::i;:::-;-1:-1:-1;;79374:34:0;;:36::i;:::-;79305:18;:115::i;:::-;79294:126;-1:-1:-1;79438:47:0;79449:25;-1:-1:-1;;79449:23:0;;;:25::i;:::-;79476:8;79438:10;:47::i;:::-;79430:84;;;;-1:-1:-1;;;79430:84:0;;11103:2:1;79430:84:0;;;11085:21:1;11142:2;11122:18;;;11115:30;11181:26;11161:18;;;11154:54;11225:18;;79430:84:0;10901:348:1;79430:84:0;79047:474;;;:::o;75372:136::-;75436:6;75468:32;-1:-1:-1;;75468:15:0;;73614:1;;75468:15;:32::i;:::-;75454:47;75372:136;-1:-1:-1;;75372:136:0:o;75601:124::-;75664:7;75690:28;-1:-1:-1;;75690:11:0;;73661:1;75715:2;75690:11;:28::i;115156:231::-;115226:5;:21;;;;;;;;;;;;115282:48;;;;;115318:10;115282:14;:48;;2662:74:1;115282:14:0;;;;;;;;;;:27;;2635:18:1;;115282:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;115360:7:0;;115345:35;;115369:10;;-1:-1:-1;115345:35:0;115360:7;;;;-1:-1:-1;115345:35:0;;115360:7;;115345:35;115156:231::o;114708:285::-;98137:19;;;;114788:81;;;;-1:-1:-1;;;114788:81:0;;11703:2:1;114788:81:0;;;11685:21:1;11742:2;11722:18;;;11715:30;11781:26;11761:18;;;11754:54;11825:18;;114788:81:0;11501:348:1;114788:81:0;114879:14;:49;;;;;;;;;;;;;;;;;;114943:43;;2662:74:1;;;114943:43:0;;2650:2:1;2635:18;114943:43:0;;;;;;;114708:285;:::o;72567:179::-;72650:7;;;;72667:21;;;;;;;;;;;72703:36;;;72650:7;;;;12089:34:1;;;12154:2;12139:18;;12132:43;;;;72703:36:0;;12001:18:1;72703:36:0;11854:327:1;63555:808:0;63952:13;;63619:4;;63952:13;;;;;63948:409;;;64006:7;:12;;64017:1;64006:12;:61;;;;-1:-1:-1;64061:4:0;98137:19;:23;64006:61;63981:166;;;;-1:-1:-1;;;63981:166:0;;12388:2:1;63981:166:0;;;12370:21:1;12427:2;12407:18;;;12400:30;12466:34;12446:18;;;12439:62;12537:16;12517:18;;;12510:44;12571:19;;63981:166:0;12186:410:1;63981:166:0;-1:-1:-1;64168:5:0;;63555:808;-1:-1:-1;63555:808:0:o;63948:409::-;64212:12;;:22;;;;:12;;:22;64204:81;;;;-1:-1:-1;;;64204:81:0;;12388:2:1;64204:81:0;;;12370:21:1;12427:2;12407:18;;;12400:30;12466:34;12446:18;;;12439:62;12537:16;12517:18;;;12510:44;12571:19;;64204:81:0;12186:410:1;64204:81:0;-1:-1:-1;64299:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;63555:808:0:o;71673:142::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;12803:2:1;62958:69:0;;;12785:21:1;12842:2;12822:18;;;12815:30;12881:34;12861:18;;;12854:62;12952:13;12932:18;;;12925:41;12983:19;;62958:69:0;12601:407:1;62958:69:0;71761:16:::1;:14;:16::i;:::-;71787:21;71799:8;71787:11;:21::i;82634:122::-:0;82691:7;82717:32;82729:5;82736:12;:10;:12::i;:::-;82717:11;:32::i;69717:187::-;69809:6;;;;69825:17;;;;;;;;;;;69857:40;;69809:6;;;69825:17;69809:6;;69857:40;;69790:16;;69857:40;69780:124;69717:187;:::o;90222:122::-;90283:7;90309:28;:5;34906:10;90309:9;:28::i;91329:183::-;91402:6;91386:5;89229:35;34906:10;34899:18;-1:-1:-1;;89229:16:0;;;;:35::i;:::-;;91486:19:::1;91499:5;91486:12;:19::i;:::-;91467:16;91477:5;91467:9;:16::i;:::-;91447:17;91458:5;91447:10;:17::i;:::-;91427;91438:5;91427:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;91420:85;;89274:1;91329:183:::0;;;;:::o;116705:814::-;116811:14;92147:24;116845:48;;116841:672;;116945:10;116909:47;113758:776;-1:-1:-1;;113758:776:0:o;116841:672::-;117349:24;:22;:24::i;:::-;-1:-1:-1;92147:24:0;116705:814;;;:::o;36091:638::-;36387:14;;36236:12;;36344:17;;35842:29;35860:10;35713:1;35842:29;:::i;:::-;36364:13;;:38;;;;:::i;:::-;36344:58;;36412:17;36452:5;:12;36432:10;:33;;;;:::i;:::-;36412:53;-1:-1:-1;34563:1:0;35842:29;35860:10;35713:1;35842:29;:::i;:::-;36561:13;;36592:10;36620;36648:7;36673:5;36696:12;36494:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;36475:247;;;;36091:638;;;;;;:::o;96588:123::-;96643:18;:4;96655:5;96643:11;:18::i;:::-;96671:15;96692:11;:4;:9;:11::i;:::-;96671:33;;;;;;;-1:-1:-1;96671:33:0;;;;;;;;;;;-1:-1:-1;96588:123:0:o;14473:359::-;14577:10;;14543:7;;14724:4;14715:14;;14799:26;;;;14715:14;14577:10;14799:5;:26::i;:::-;14792:33;14473:359;-1:-1:-1;;;;;14473:359:0:o;75831:155::-;75894:7;75920:59;-1:-1:-1;;75920:11:0;;75894:7;73720:2;75894:7;75920:11;:59::i;76069:172::-;76137:7;76163:71;73720:2;76193:37;73720:2;17310;17306:16;;;3488:26;17302:28;76193:37;:::i;:::-;-1:-1:-1;;76163:11:0;;;:71;76232:1;76163:11;:71::i;29126:632::-;29181:16;29209:11;29230:12;29245;29249:7;17310:2;17306:16;3488:26;17302:28;;17064:282;29245:12;29230:27;;;;29367:4;29361:11;29354:18;;29422:3;29415:10;;29468:33;29481:7;29490:3;29496:4;29490:10;29468:12;:33::i;:::-;-1:-1:-1;29625:14:0;;;29641:4;29621:25;29615:4;29608:39;29688:17;;29126:632;;-1:-1:-1;29126:632:0:o;76568:285::-;76678:14;;76725;-1:-1:-1;;76725:12:0;;;:14::i;:::-;76708:31;;76758:36;76787:6;52303:58;;21315:66:1;52303:58:0;;;21303:79:1;21398:12;;;21391:28;;;52173:7:0;;21435:12:1;;52303:58:0;;;;;;;;;;;;52293:69;;;;;;52286:76;;52104:265;;;;76758:36;76749:45;;76813:33;76827:6;76835:10;76813:13;:33::i;:::-;76804:42;76568:285;-1:-1:-1;;;;76568:285:0:o;75115:143::-;75180:6;75212:38;-1:-1:-1;;75212:15:0;;75180:6;75248:1;75212:15;:38::i;115935:236::-;116057:4;116100:11;116085:26;;:11;:26;;;116077:51;;;;-1:-1:-1;;;116077:51:0;;15823:2:1;116077:51:0;;;15805:21:1;15862:2;15842:18;;;15835:30;15901:14;15881:18;;;15874:42;15933:18;;116077:51:0;15621:336:1;116077:51:0;-1:-1:-1;116157:7:0;;;;;;116145:19;;;;115935:236;-1:-1:-1;115935:236:0:o;21939:221::-;22058:14;22136:11;22141:6;22136:2;:11;:::i;:::-;22135:17;;22151:1;22135:17;:::i;:::-;22091:62;;22099:30;22105:7;22114:6;22122;22099:5;:30::i;:::-;22091:62;;;21939:221;-1:-1:-1;;;;21939:221:0:o;20822:771::-;20937:14;20967:6;:11;;20977:1;20967:11;20963:59;;-1:-1:-1;21009:1:0;20994:17;;20963:59;21053:12;21057:7;17310:2;17306:16;3488:26;17302:28;;17064:282;21053:12;21035:30;;:15;;;;:6;:15;:::i;:::-;:30;21031:137;;;21088:68;21104:12;21108:7;16204:3;16200:17;3488:26;16196:29;;15877:364;21104:12;21088:68;;21118:12;21122:7;17310:2;17306:16;3488:26;17302:28;;17064:282;21118:12;21088:68;;21132:6;21148;21140:15;;21088;:68::i;:::-;21081:76;;-1:-1:-1;;;21081:76:0;;;;;;;;:::i;21031:137::-;21195:2;21185:6;:12;;;;21177:83;;;;-1:-1:-1;;;21177:83:0;;16721:2:1;21177:83:0;;;16703:21:1;16760:2;16740:18;;;16733:30;16799:34;16779:18;;;16772:62;16870:28;16850:18;;;16843:56;16916:19;;21177:83:0;16519:422:1;21177:83:0;21341:1;21332:10;;21271:15;21377:12;21381:7;16204:3;16200:17;3488:26;16196:29;;15877:364;21377:12;21362:27;;;-1:-1:-1;21399:13:0;8306:66;8276:12;;;8255:131;21551:17;;;;21545:24;21541:36;;;-1:-1:-1;;;;;20822:771:0:o;68195:95::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;12803:2:1;62958:69:0;;;12785:21:1;12842:2;12822:18;;;12815:30;12881:34;12861:18;;;12854:62;12952:13;12932:18;;;12925:41;12983:19;;62958:69:0;12601:407:1;62958:69:0;68257:26:::1;:24;:26::i;82874:964::-:0;82919:34;;:::i;:::-;82978:3;82965:16;;83004:3;82965:10;82991;;:16;83030:3;83017:10;;;:16;83056:3;83043:10;;;:16;83082:3;83069:10;;;:16;83108:3;83095:10;;;:16;83134:3;83121:10;;;:16;83160:3;83147:10;;;:16;83186:3;83173:10;;;:16;83212:3;83199:10;;;:16;83239:4;83225:11;;;:18;83267:4;83253:11;;;:18;83295:4;83281:11;;;:18;83323:4;83309:11;;;:18;83351:4;83337:11;;;:18;83379:4;83365:11;;;:18;83407:4;83393:11;;;:18;83435:4;83421:11;;;:18;83463:4;83449:11;;;:18;83491:4;83477:11;;;:18;83519:4;83505:11;;;:18;83547:4;83533:11;;;:18;83575:4;83561:11;;;:18;83603:4;83589:11;;;:18;83631:4;83617:11;;;:18;83659:4;83645:11;;;:18;83687:4;83673:11;;;:18;83715:4;83701:11;;;:18;83743:4;83729:11;;;:18;83771:4;83757:11;;;:18;83799:4;83785:11;;;:18;83827:4;83813:11;;;:18;82965:7;82874:964::o;81978:589::-;82151:11;;;;82102:16;;;82173:388;80558:2;82193:1;:14;82173:388;;;82259:4;82244:11;;;82243:20;;;82281:12;;;82277:215;;82351:5;82364:1;82351:15;;;;;;;:::i;:::-;;;82334:43;;;;;;17103:19:1;;;;17138:12;;17131:28;;;17175:12;;82334:43:0;;;;;;;;;;;;82324:54;;;;;;82313:65;;82277:215;;;82455:8;82465:7;82473:1;82465:10;;;;;;;:::i;:::-;;;;;82438:38;;;;;;;;17103:19:1;;;17147:2;17138:12;;17131:28;17184:2;17175:12;;16946:247;82438:38:0;;;;;;;;;;;;;82428:49;;;;;;82417:60;;82277:215;-1:-1:-1;82533:3:0;;82173:388;;;;82124:443;81978:589;;;;:::o;10891:578::-;10969:7;10993:26;11000:7;11009:9;10993:6;:26::i;:::-;10988:451;;11038:9;11051:35;11069:15;11076:7;15235:3;15231:17;;15024:268;11069:15;11061:24;;11051:9;:35::i;:::-;11035:51;;;11103:9;11116:29;11134:9;11126:18;;11116:9;:29::i;:::-;11203:186;;17565:31:1;11203:186:0;;;17553:44:1;17616:66;17720:3;17716:16;;;17712:25;;17698:12;;;17691:47;17768:15;17754:12;;;17747:37;17818:16;;;17814:25;17800:12;;;17793:47;11100:45:0;;-1:-1:-1;11159:17:0;;-1:-1:-1;17856:12:1;;11203:186:0;;;;;;;;;;;;11159:244;;11424:3;11417:11;;-1:-1:-1;;;11417:11:0;;;;;;;;:::i;10988:451::-;-1:-1:-1;11455:7:0;;10891:578;-1:-1:-1;10891:578:0:o;91170:153::-;91246:6;91230:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;91278:37:0::1;-1:-1:-1::0;;91278:15:0;::::1;89177:2;91312;91278:15;:37::i;:::-;91264:52;;::::0;91170:153;-1:-1:-1;;;91170:153:0:o;90974:147::-;91047:6;91031:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;91079:34:0::1;-1:-1:-1::0;;91079:15:0;::::1;89124:2;91110;91079:15;:34::i;90779:149::-:0;90853:6;90837:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;90885:35:0::1;-1:-1:-1::0;;90885:15:0;::::1;89074:2;90917;90885:15;:35::i;90583:149::-:0;90657:6;90641:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;90689:35:0::1;-1:-1:-1::0;;90689:15:0;::::1;89024:1;90721:2;90689:15;:35::i;72329:132::-:0;72417:15;;;;72395:10;:38;72387:67;;;;-1:-1:-1;;;72387:67:0;;18081:2:1;72387:67:0;;;18063:21:1;18120:2;18100:18;;;18093:30;18159:18;18139;;;18132:46;18195:18;;72387:67:0;17879:340:1;81017:750:0;81102:11;;;;;;80621:1;;80605:13;;:1;:13;:::i;:::-;:17;;;;:::i;:::-;81131:4;:17;81123:46;;;;-1:-1:-1;;;81123:46:0;;19920:2:1;81123:46:0;;;19902:21:1;19959:2;19939:18;;;19932:30;19998:18;19978;;;19971:46;20034:18;;81123:46:0;19718:340:1;81123:46:0;81204:6;;81230:11;;;:18;;;81263:9;81258:319;80558:2;81278:1;:14;81258:319;;;81315:4;81322:1;81315:8;81328:1;81314:15;81310:101;;81367:5;81349;81362:1;81349:15;;;;;;;:::i;:::-;;:23;-1:-1:-1;;;;81017:750:0:o;81310:101::-;81459:5;81472:1;81459:15;;;;;;;:::i;:::-;;;81442:40;;;;;;17103:19:1;;;;17138:12;;17131:28;;;17175:12;;81442:40:0;;;;;;;;;;;;;81432:51;;81442:40;81432:51;;;;;-1:-1:-1;81506:1:0;81497:10;;;;81549:3;81258:319;;;-1:-1:-1;81747:13:0;;:::i;:::-;81077:690;81017:750;;:::o;13614:462::-;13725:15;;13767:11;13774:4;13767;:11;:::i;:::-;13752:26;;13893:4;13887:11;13881:4;13878:21;13875:66;;;-1:-1:-1;13926:1:0;13875:66;13964:4;13972:1;13964:9;13960:51;;-1:-1:-1;;13989:11:0;;;;;13960:51;-1:-1:-1;;12883:2:0;12879:27;;;12953:17;;;;12945:26;;;13017:17;13013:2;13009:26;;13614:462::o;17947:399::-;18086:7;18105:12;18120;18124:7;16204:3;16200:17;3488:26;16196:29;;15877:364;18120:12;18105:27;;;;18216:12;18220:7;18216:3;:12::i;:::-;18209:4;18193:13;18200:6;18193:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;18189:77;;;-1:-1:-1;;18244:11:0;;;;;18189:77;18283:13;18290:6;18283:4;:13;:::i;:::-;18276:20;;18313:26;18319:7;18313:26;;18328:4;18334;18313:5;:26::i;:::-;18306:33;17947:399;-1:-1:-1;;;;;;17947:399:0:o;27854:902::-;27932:15;-1:-1:-1;;8790:15:0;;;;27959:69;;;;-1:-1:-1;;;27959:69:0;;20454:2:1;27959:69:0;;;20436:21:1;20493:2;20473:18;;;20466:30;20532:34;20512:18;;;20505:62;20603:10;20583:18;;;20576:38;20631:19;;27959:69:0;20252:404:1;27959:69:0;28046:16;28054:7;28046;:16::i;:::-;28038:72;;;;-1:-1:-1;;;28038:72:0;;20863:2:1;28038:72:0;;;20845:21:1;20902:2;20882:18;;;20875:30;20941:34;20921:18;;;20914:62;21012:13;20992:18;;;20985:41;21043:19;;28038:72:0;20661:407:1;28038:72:0;28120:12;28135;28139:7;17310:2;17306:16;3488:26;17302:28;;17064:282;28135:12;28120:27;;;;28157:15;28175:12;28179:7;16204:3;16200:17;3488:26;16196:29;;15877:364;28175:12;28157:30;;;;28198:11;28319:4;28313:11;28306:18;;28406:7;28401:3;28398:16;28395:94;;;28446:4;28440;28433:18;28395:94;28661:4;28652:7;28646:4;28637:7;28634:1;28627:5;28616:50;28612:55;28697:52;28718:15;28725:7;15235:3;15231:17;;15024:268;28718:15;12879:27;12883:2;12879:27;;;;12953:17;;12945:26;;13017:17;;13013:2;13009:26;;12629:446;23273:290;23329:14;23355:12;23370;23374:7;16204:3;16200:17;3488:26;16196:29;;15877:364;23370:12;23355:27;;;;23392:12;23407;23411:7;17310:2;17306:16;3488:26;17302:28;;17064:282;23407:12;23392:27;;23526:21;;;;23273:290;-1:-1:-1;;;23273:290:0:o;48400:227::-;48478:7;48498:17;48517:18;48539:27;48550:4;48556:9;48539:10;:27::i;:::-;48497:69;;;;48576:18;48588:5;48576:11;:18::i;:::-;-1:-1:-1;48611:9:0;48400:227;-1:-1:-1;;;48400:227:0:o;19579:741::-;19725:17;19757:9;19770:15;19780:4;19770:9;:15::i;:::-;19754:31;;;19798:9;19811:15;19821:4;19811:9;:15::i;:::-;19795:31;;;19839:9;19852:17;19862:6;19852:9;:17::i;:::-;19836:33;;;19882:9;19895:17;19905:6;19895:9;:17::i;:::-;19879:33;;;20062:1;20124;20204;20266;19948:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19922:391;;19744:576;;;;19579:741;;;;;;:::o;68296:111::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;12803:2:1;62958:69:0;;;12785:21:1;12842:2;12822:18;;;12815:30;12881:34;12861:18;;;12854:62;12952:13;12932:18;;;12925:41;12983:19;;62958:69:0;12601:407:1;62958:69:0;68368:32:::1;67483:10:::0;68368:18:::1;:32::i;10461:132::-:0;10535:4;10577:9;10558:28;;:15;10565:7;15235:3;15231:17;;15024:268;10558:15;:28;;;;10461:132;-1:-1:-1;;;10461:132:0:o;5849:667::-;5903:13;;5959:2;5944:258;5967:2;5963:1;:6;;;5944:258;;;5987:11;6014:5;:1;6018;6014:5;:::i;:::-;6007:13;;:2;:13;;5987:34;;6044:14;6052:5;6044:7;:14::i;:::-;6035:23;;;;;;6076:1;:7;;6081:2;6076:7;6072:58;;6113:2;6103:12;;;;;6072:58;-1:-1:-1;6171:6:0;;5944:258;;;-1:-1:-1;6265:2:0;6250:260;6273:3;6269:1;:7;;;6250:260;;;6294:11;6321:5;:1;6325;6321:5;:::i;:::-;6314:13;;:2;:13;;6294:34;;6352:14;6360:5;6352:7;:14::i;:::-;6342:24;;;;;;6384:1;:6;;6389:1;6384:6;6380:58;;6421:2;6410:13;;;;;6380:58;-1:-1:-1;6479:6:0;;6250:260;;;;5849:667;;;:::o;17520:147::-;17573:7;17638:12;17642:7;17310:2;17306:16;3488:26;17302:28;;17064:282;17638:12;17623;17627:7;16204:3;16200:17;3488:26;16196:29;;15877:364;17623:12;:27;17616:34;;;;17520:147;;;:::o;9463:333::-;9520:8;9544:15;9551:7;15235:3;15231:17;;15024:268;9544:15;:31;;9563:12;9544:31;9540:74;;-1:-1:-1;9598:5:0;;9463:333;-1:-1:-1;9463:333:0:o;9540:74::-;9623:12;9638;9642:7;9638:3;:12::i;:::-;9773:4;9767:11;-1:-1:-1;9754:26:0;;9463:333;-1:-1:-1;;;9463:333:0:o;46335:1279::-;46416:7;46425:12;46646:9;:16;46666:2;46646:22;46642:966;;46935:4;46920:20;;46914:27;46984:4;46969:20;;46963:27;47041:4;47026:20;;47020:27;46684:9;47012:36;47082:25;47093:4;47012:36;46914:27;46963;47082:10;:25::i;:::-;47075:32;;;;;;;;;46642:966;47128:9;:16;47148:2;47128:22;47124:484;;47397:4;47382:20;;47376:27;47447:4;47432:20;;47426:27;47487:23;47498:4;47376:27;47426;47487:10;:23::i;:::-;47480:30;;;;;;;;47124:484;-1:-1:-1;47557:1:0;;-1:-1:-1;47561:35:0;47124:484;46335:1279;;;;;:::o;44640:631::-;44717:20;44708:5;:29;;;;;;;;:::i;:::-;;44704:561;;44640:631;:::o;44704:561::-;44813:29;44804:5;:38;;;;;;;;:::i;:::-;;44800:465;;44858:34;;-1:-1:-1;;;44858:34:0;;23175:2:1;44858:34:0;;;23157:21:1;23214:2;23194:18;;;23187:30;23253:26;23233:18;;;23226:54;23297:18;;44858:34:0;22973:348:1;44800:465:0;44922:35;44913:5;:44;;;;;;;;:::i;:::-;;44909:356;;44973:41;;-1:-1:-1;;;44973:41:0;;23528:2:1;44973:41:0;;;23510:21:1;23567:2;23547:18;;;23540:30;23606:33;23586:18;;;23579:61;23657:18;;44973:41:0;23326:355:1;44909:356:0;45044:30;45035:5;:39;;;;;;;;:::i;:::-;;45031:234;;45090:44;;-1:-1:-1;;;45090:44:0;;23888:2:1;45090:44:0;;;23870:21:1;23927:2;23907:18;;;23900:30;23966:34;23946:18;;;23939:62;24037:4;24017:18;;;24010:32;24059:19;;45090:44:0;23686:398:1;45031:234:0;45164:30;45155:5;:39;;;;;;;;:::i;:::-;;45151:114;;45210:44;;-1:-1:-1;;;45210:44:0;;24291:2:1;45210:44:0;;;24273:21:1;24330:2;24310:18;;;24303:30;24369:34;24349:18;;;24342:62;24440:4;24420:18;;;24413:32;24462:19;;45210:44:0;24089:398:1;5326:199:0;5376:14;5413:18;5429:1;5423:2;:7;;;;5413:9;:18::i;:::-;5402:29;;5455:13;;;;;;5467:1;5455:13;5489;5499:2;5489:9;:13::i;:::-;5478:24;;;;5326:199;-1:-1:-1;5326:199:0:o;49808:1603::-;49934:7;;50858:66;50845:79;;50841:161;;;-1:-1:-1;50956:1:0;;-1:-1:-1;50960:30:0;50940:51;;50841:161;51015:1;:7;;51020:2;51015:7;;:18;;;;;51026:1;:7;;51031:2;51026:7;;51015:18;51011:100;;;-1:-1:-1;51065:1:0;;-1:-1:-1;51069:30:0;51049:51;;51011:100;51222:24;;;51205:14;51222:24;;;;;;;;;24719:25:1;;;24792:4;24780:17;;24760:18;;;24753:45;;;;24814:18;;;24807:34;;;24857:18;;;24850:34;;;51222:24:0;;24691:19:1;;51222:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51222:24:0;;;;;;-1:-1:-1;;51260:20:0;;;51256:101;;51312:1;51316:29;51296:50;;;;;;;51256:101;51375:6;-1:-1:-1;51383:20:0;;-1:-1:-1;49808:1603:0;;;;;;;;:::o;48881:336::-;48991:7;;49049:66;49036:80;;48991:7;49142:25;49158:3;49143:18;;;49165:2;49142:25;:::i;:::-;49126:42;;49185:25;49196:4;49202:1;49205;49208;49185:10;:25::i;:::-;49178:32;;;;;;48881:336;;;;;;:::o;3761:1393::-;3813:10;3979:4;3974:9;;;;4025:15;;;;;4021:57;;-1:-1:-1;4063:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4021:57::-;4096:7;:15;;4107:4;4096:15;4092:57;;-1:-1:-1;4134:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4092:57::-;4167:7;:15;;4178:4;4167:15;4163:57;;-1:-1:-1;4205:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4163:57::-;4238:7;:15;;4249:4;4238:15;4234:57;;-1:-1:-1;4276:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4234:57::-;4309:7;:15;;4320:4;4309:15;4305:57;;-1:-1:-1;4347:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4305:57::-;4380:7;:15;;4391:4;4380:15;4376:57;;-1:-1:-1;4418:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4376:57::-;4451:7;:15;;4462:4;4451:15;4447:57;;-1:-1:-1;4489:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4447:57::-;4522:7;:15;;4533:4;4522:15;4518:57;;-1:-1:-1;4560:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4518:57::-;4593:7;:15;;4604:4;4593:15;4589:57;;-1:-1:-1;4631:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4589:57::-;4664:7;:15;;4675:4;4664:15;4660:57;;-1:-1:-1;4702:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4660:57::-;4735:7;:15;;4746:4;4735:15;4731:57;;-1:-1:-1;4773:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4731:57::-;4806:7;:15;;4817:4;4806:15;4802:57;;-1:-1:-1;4844:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4802:57::-;4877:7;:15;;4888:4;4877:15;4873:57;;-1:-1:-1;4915:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4873:57::-;4948:7;:15;;4959:4;4948:15;4944:57;;-1:-1:-1;4986:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4944:57::-;5019:7;:15;;5030:4;5019:15;5015:57;;-1:-1:-1;5057:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;5015:57::-;5090:7;:15;;5101:4;5090:15;5086:57;;-1:-1:-1;5128:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:184:1:-;248:77;245:1;238:88;345:4;342:1;335:15;369:4;366:1;359:15;385:777;427:5;480:3;473:4;465:6;461:17;457:27;447:55;;498:1;495;488:12;447:55;534:6;521:20;560:18;597:2;593;590:10;587:36;;;603:18;;:::i;:::-;737:2;731:9;799:4;791:13;;642:66;787:22;;;811:2;783:31;779:40;767:53;;;835:18;;;855:22;;;832:46;829:72;;;881:18;;:::i;:::-;921:10;917:2;910:22;956:2;948:6;941:18;1002:3;995:4;990:2;982:6;978:15;974:26;971:35;968:55;;;1019:1;1016;1009:12;968:55;1083:2;1076:4;1068:6;1064:17;1057:4;1049:6;1045:17;1032:54;1130:1;1123:4;1118:2;1110:6;1106:15;1102:26;1095:37;1150:6;1141:15;;;;;;385:777;;;;:::o;1167:320::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;1344:9;1331:23;1377:18;1369:6;1366:30;1363:50;;;1409:1;1406;1399:12;1363:50;1432:49;1473:7;1464:6;1453:9;1449:22;1432:49;:::i;1952:180::-;2011:6;2064:2;2052:9;2043:7;2039:23;2035:32;2032:52;;;2080:1;2077;2070:12;2032:52;-1:-1:-1;2103:23:1;;1952:180;-1:-1:-1;1952:180:1:o;2747:154::-;2833:42;2826:5;2822:54;2815:5;2812:65;2802:93;;2891:1;2888;2881:12;2906:247;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3073:9;3060:23;3092:31;3117:5;3092:31;:::i;3688:184::-;3740:77;3737:1;3730:88;3837:4;3834:1;3827:15;3861:4;3858:1;3851:15;3877:396;4020:2;4005:18;;4053:1;4042:13;;4032:201;;4089:77;4086:1;4079:88;4190:4;4187:1;4180:15;4218:4;4215:1;4208:15;4032:201;4242:25;;;3877:396;:::o;4808:163::-;4875:20;;4935:10;4924:22;;4914:33;;4904:61;;4961:1;4958;4951:12;4976:753;5087:6;5095;5103;5111;5119;5172:3;5160:9;5151:7;5147:23;5143:33;5140:53;;;5189:1;5186;5179:12;5140:53;5212:28;5230:9;5212:28;:::i;:::-;5202:38;;5287:2;5276:9;5272:18;5259:32;5249:42;;5310:37;5343:2;5332:9;5328:18;5310:37;:::i;:::-;5300:47;;5398:2;5387:9;5383:18;5370:32;5421:18;5462:2;5454:6;5451:14;5448:34;;;5478:1;5475;5468:12;5448:34;5501:49;5542:7;5533:6;5522:9;5518:22;5501:49;:::i;:::-;5491:59;;5603:3;5592:9;5588:19;5575:33;5559:49;;5633:2;5623:8;5620:16;5617:36;;;5649:1;5646;5639:12;5617:36;;5672:51;5715:7;5704:8;5693:9;5689:24;5672:51;:::i;:::-;5662:61;;;4976:753;;;;;;;;:::o;6264:184::-;6316:77;6313:1;6306:88;6413:4;6410:1;6403:15;6437:4;6434:1;6427:15;6453:258;6525:1;6535:113;6549:6;6546:1;6543:13;6535:113;;;6625:11;;;6619:18;6606:11;;;6599:39;6571:2;6564:10;6535:113;;;6666:6;6663:1;6660:13;6657:48;;;6701:1;6692:6;6687:3;6683:16;6676:27;6657:48;;6453:258;;;:::o;6716:316::-;6757:3;6795:5;6789:12;6822:6;6817:3;6810:19;6838:63;6894:6;6887:4;6882:3;6878:14;6871:4;6864:5;6860:16;6838:63;:::i;:::-;6946:2;6934:15;6951:66;6930:88;6921:98;;;;7021:4;6917:109;;6716:316;-1:-1:-1;;6716:316:1:o;7037:337::-;7224:42;7216:6;7212:55;7201:9;7194:74;7304:2;7299;7288:9;7284:18;7277:30;7175:4;7324:44;7364:2;7353:9;7349:18;7341:6;7324:44;:::i;7379:184::-;7431:77;7428:1;7421:88;7528:4;7525:1;7518:15;7552:4;7549:1;7542:15;7568:125;7608:4;7636:1;7633;7630:8;7627:34;;;7641:18;;:::i;:::-;-1:-1:-1;7678:9:1;;7568:125::o;8403:251::-;8473:6;8526:2;8514:9;8505:7;8501:23;8497:32;8494:52;;;8542:1;8539;8532:12;8494:52;8574:9;8568:16;8593:31;8618:5;8593:31;:::i;9939:228::-;9978:3;10006:10;10043:2;10040:1;10036:10;10073:2;10070:1;10066:10;10104:3;10100:2;10096:12;10091:3;10088:21;10085:47;;;10112:18;;:::i;:::-;10148:13;;9939:228;-1:-1:-1;;;;9939:228:1:o;10172:377::-;10365:2;10354:9;10347:21;10328:4;10391:44;10431:2;10420:9;10416:18;10408:6;10391:44;:::i;:::-;10483:9;10475:6;10471:22;10466:2;10455:9;10451:18;10444:50;10511:32;10536:6;10528;10511:32;:::i;13013:244::-;13052:3;13080:26;13133:2;13130:1;13126:10;13163:2;13160:1;13156:10;13194:3;13190:2;13186:12;13181:3;13178:21;13175:47;;;13202:18;;:::i;14071:238::-;14109:7;14149:4;14146:1;14142:12;14181:4;14178:1;14174:12;14241:3;14235:4;14231:14;14226:3;14223:23;14216:3;14209:11;14202:19;14198:49;14195:75;;;14250:18;;:::i;:::-;14290:13;;14071:238;-1:-1:-1;;;14071:238:1:o;14314:224::-;14353:3;14381:6;14414:2;14411:1;14407:10;14444:2;14441:1;14437:10;14475:3;14471:2;14467:12;14462:3;14459:21;14456:47;;;14483:18;;:::i;14543:1073::-;14868:3;14896:66;15005:2;14996:6;14991:3;14987:16;14983:25;14978:3;14971:38;15060:2;15051:6;15046:3;15042:16;15038:25;15034:1;15029:3;15025:11;15018:46;15115:2;15106:6;15101:3;15097:16;15093:25;15089:1;15084:3;15080:11;15073:46;15170:2;15161:6;15156:3;15152:16;15148:25;15144:1;15139:3;15135:11;15128:46;;15203:6;15197:13;15219:61;15273:6;15269:1;15264:3;15260:11;15253:4;15245:6;15241:17;15219:61;:::i;:::-;15340:13;;15299:16;;;;15362:62;15340:13;15411:1;15403:10;;15396:4;15384:17;;15362:62;:::i;:::-;15485:13;;15443:17;;;15507:62;15485:13;15556:1;15548:10;;15541:4;15529:17;;15507:62;:::i;:::-;15589:17;15608:1;15585:25;;14543:1073;-1:-1:-1;;;;;;;;;14543:1073:1:o;15962:195::-;16000:4;16037;16034:1;16030:12;16069:4;16066:1;16062:12;16094:3;16089;16086:12;16083:38;;;16101:18;;:::i;:::-;16138:13;;;15962:195;-1:-1:-1;;;15962:195:1:o;16162:128::-;16202:3;16233:1;16229:6;16226:1;16223:13;16220:39;;;16239:18;;:::i;:::-;-1:-1:-1;16275:9:1;;16162:128::o;16295:219::-;16444:2;16433:9;16426:21;16407:4;16464:44;16504:2;16493:9;16489:18;16481:6;16464:44;:::i;18224:482::-;18313:1;18356:5;18313:1;18370:330;18391:7;18381:8;18378:21;18370:330;;;18510:4;18442:66;18438:77;18432:4;18429:87;18426:113;;;18519:18;;:::i;:::-;18569:7;18559:8;18555:22;18552:55;;;18589:16;;;;18552:55;18668:22;;;;18628:15;;;;18370:330;;;18374:3;18224:482;;;;;:::o;18711:866::-;18760:5;18790:8;18780:80;;-1:-1:-1;18831:1:1;18845:5;;18780:80;18879:4;18869:76;;-1:-1:-1;18916:1:1;18930:5;;18869:76;18961:4;18979:1;18974:59;;;;19047:1;19042:130;;;;18954:218;;18974:59;19004:1;18995:10;;19018:5;;;19042:130;19079:3;19069:8;19066:17;19063:43;;;19086:18;;:::i;:::-;-1:-1:-1;;19142:1:1;19128:16;;19157:5;;18954:218;;19256:2;19246:8;19243:16;19237:3;19231:4;19228:13;19224:36;19218:2;19208:8;19205:16;19200:2;19194:4;19191:12;19187:35;19184:77;19181:159;;;-1:-1:-1;19293:19:1;;;19325:5;;19181:159;19372:34;19397:8;19391:4;19372:34;:::i;:::-;19502:6;19434:66;19430:79;19421:7;19418:92;19415:118;;;19513:18;;:::i;19582:131::-;19642:5;19671:36;19698:8;19692:4;19671:36;:::i;20063:184::-;20115:77;20112:1;20105:88;20212:4;20209:1;20202:15;20236:4;20233:1;20226:15;21577:1391;22299:34;22287:47;;22364:23;22359:2;22350:12;;22343:45;22407:66;22511:3;22507:16;;;22503:25;;22498:2;22489:12;;22482:47;22548:17;22590:2;22581:12;;22574:24;;;22632:16;;;22628:25;;22623:2;22614:12;;22607:47;22684:34;22679:2;22670:12;;22663:56;22750:3;22744;22735:13;;22728:26;22789:16;;;22785:25;;22779:3;22770:13;;22763:48;22836:3;22827:13;;22820:25;22880:16;;;22876:25;22870:3;22861:13;;22854:48;21535:3;22957;22948:13;;21523:16;-1:-1:-1;21555:11:1;;;22918:44;21458:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"leafIndex","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"destinationAndNonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"tips","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Dispatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"ImproperAttestation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updaterManager","type":"address"}],"name":"NewUpdaterManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"address","name":"reporter","type":"address"}],"name":"UpdaterSlashed","type":"event"},{"inputs":[],"name":"MAX_MESSAGE_BODY_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipientAddress","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"improperAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUpdaterManager","name":"_updaterManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterManager","type":"address"}],"name":"setUpdaterManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Home.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"suggestUpdate","outputs":[{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updaterManager","outputs":[{"internalType":"contract IUpdaterManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"notice":"Emitted when a new message is dispatched via Nomad"},"ImproperAttestation(address,bytes)":{"notice":"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state"},"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"NewUpdaterManager(address)":{"notice":"Emitted when the UpdaterManager contract is changed"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"},"UpdaterSlashed(address,address)":{"notice":"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)"}},"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"notice":"Dispatch the message to the destination domain \u0026 recipient"},"improperAttestation(bytes)":{"notice":"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation."},"root()":{"notice":"Calculates and returns tree's current root"},"setUpdater(address)":{"notice":"Set a new Updater"},"setUpdaterManager(address)":{"notice":"Set a new UpdaterManager contract"},"suggestUpdate()":{"notice":"Suggest an update for the Updater to sign and submit."}},"version":1},"developerDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"params":{"destinationAndNonce":"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)","leafIndex":"Index of message's leaf in merkle tree","message":"Raw bytes of message","messageHash":"Hash of message; the leaf inserted to the Merkle tree for the message","tips":"Tips paid for the remote off-chain agents"}},"ImproperAttestation(address,bytes)":{"params":{"attestation":"Attestation data and signature","updater":"Updater who signed improper attestation"}},"NewUpdaterManager(address)":{"params":{"updaterManager":"The address of the new updaterManager"}},"UpdaterSlashed(address,address)":{"params":{"reporter":"The address of the entity that reported the updater misbehavior","updater":"The address of the updater"}}},"kind":"dev","methods":{"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"details":"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.","params":{"_destinationDomain":"Domain of destination chain","_messageBody":"Raw bytes content of message","_recipientAddress":"Address of recipient on destination chain as bytes32"}},"improperAttestation(bytes)":{"details":"Reverts (and doesn't slash updater) if signature is invalid or update not current","params":{"_attestation":"Attestation data and signature"},"returns":{"_0":"TRUE if update was an Improper Attestation (implying Updater was slashed)"}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setUpdater(address)":{"details":"To be set when rotating Updater after Fraud","params":{"_updater":"the new Updater"}},"setUpdaterManager(address)":{"details":"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation","params":{"_updaterManager":"the new UpdaterManager contract"}},"suggestUpdate()":{"details":"If no messages have been sent, null bytes returned for both","returns":{"_nonce":"Current nonce","_root":"Current merkle root"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum Home.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"params\":{\"destinationAndNonce\":\"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\",\"leafIndex\":\"Index of message's leaf in merkle tree\",\"message\":\"Raw bytes of message\",\"messageHash\":\"Hash of message; the leaf inserted to the Merkle tree for the message\",\"tips\":\"Tips paid for the remote off-chain agents\"}},\"ImproperAttestation(address,bytes)\":{\"params\":{\"attestation\":\"Attestation data and signature\",\"updater\":\"Updater who signed improper attestation\"}},\"NewUpdaterManager(address)\":{\"params\":{\"updaterManager\":\"The address of the new updaterManager\"}},\"UpdaterSlashed(address,address)\":{\"params\":{\"reporter\":\"The address of the entity that reported the updater misbehavior\",\"updater\":\"The address of the updater\"}}},\"kind\":\"dev\",\"methods\":{\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"details\":\"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.\",\"params\":{\"_destinationDomain\":\"Domain of destination chain\",\"_messageBody\":\"Raw bytes content of message\",\"_recipientAddress\":\"Address of recipient on destination chain as bytes32\"}},\"improperAttestation(bytes)\":{\"details\":\"Reverts (and doesn't slash updater) if signature is invalid or update not current\",\"params\":{\"_attestation\":\"Attestation data and signature\"},\"returns\":{\"_0\":\"TRUE if update was an Improper Attestation (implying Updater was slashed)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setUpdater(address)\":{\"details\":\"To be set when rotating Updater after Fraud\",\"params\":{\"_updater\":\"the new Updater\"}},\"setUpdaterManager(address)\":{\"details\":\"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\",\"params\":{\"_updaterManager\":\"the new UpdaterManager contract\"}},\"suggestUpdate()\":{\"details\":\"If no messages have been sent, null bytes returned for both\",\"returns\":{\"_nonce\":\"Current nonce\",\"_root\":\"Current merkle root\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"notice\":\"Emitted when a new message is dispatched via Nomad\"},\"ImproperAttestation(address,bytes)\":{\"notice\":\"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state\"},\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"NewUpdaterManager(address)\":{\"notice\":\"Emitted when the UpdaterManager contract is changed\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"},\"UpdaterSlashed(address,address)\":{\"notice\":\"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)\"}},\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Dispatch the message to the destination domain \u0026 recipient\"},\"improperAttestation(bytes)\":{\"notice\":\"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation.\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"},\"setUpdater(address)\":{\"notice\":\"Set a new Updater\"},\"setUpdaterManager(address)\":{\"notice\":\"Set a new UpdaterManager contract\"},\"suggestUpdate()\":{\"notice\":\"Suggest an update for the Updater to sign and submit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Home\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"MAX_MESSAGE_BODY_BYTES()":"522ae002","VERSION()":"ffa1ad74","count()":"06661abd","dispatch(uint32,bytes32,uint32,bytes,bytes)":"f7560e40","historicalRoots(uint256)":"7ea97f40","improperAttestation(bytes)":"0afe7f90","initialize(address)":"c4d66de8","localDomain()":"8d3638f4","nonce()":"affed0e0","owner()":"8da5cb5b","renounceOwnership()":"715018a6","root()":"ebf0c717","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","setUpdaterManager(address)":"9776120e","state()":"c19d93fb","suggestUpdate()":"36e104de","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","tree()":"fd54b228","updater()":"df034cd0","updaterManager()":"9df6c8e1"}},"solidity/HomeHarness.sol:HomeHarness":{"code":"0x60a06040523480156200001157600080fd5b50604051620037f0380380620037f0833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b6080516137546200009c600039600081816102d601528181610e8601526118ee01526137546000f3fe6080604052600436106101a15760003560e01c80639df6c8e1116100e1578063da180e701161008a578063f2fde38b11610064578063f2fde38b14610519578063f7560e4014610539578063fd54b2281461054c578063ffa1ad741461056357600080fd5b8063da180e701461049e578063df034cd0146104d7578063ebf0c7171461050457600080fd5b8063c19d93fb116100bb578063c19d93fb1461040d578063c4d66de814610451578063ccbdf9c91461047157600080fd5b80639df6c8e114610399578063affed0e0146103cf578063b7bc563e146103ed57600080fd5b8063522ae0021161014e5780638d3638f4116101285780638d3638f4146102c45780638da5cb5b1461030d5780639776120e146103595780639d54f4191461037957600080fd5b8063522ae00214610279578063715018a61461028f5780637ea97f40146102a457600080fd5b8063146901db1161017f578063146901db1461021157806336e104de1461022857806348639d241461025957600080fd5b806306661abd146101a6578063089d2894146101ca5780630afe7f90146101e1575b600080fd5b3480156101b257600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101d657600080fd5b506101b761014b5481565b3480156101ed57600080fd5b506102016101fc366004612fda565b61058a565b60405190151581526020016101c1565b34801561021d57600080fd5b506102266106e0565b005b34801561023457600080fd5b5061023d6106ea565b6040805163ffffffff90931683526020830191909152016101c1565b34801561026557600080fd5b5061022661027436600461300f565b610731565b34801561028557600080fd5b506101b761080081565b34801561029b57600080fd5b5061022661073f565b3480156102b057600080fd5b506101b76102bf36600461300f565b6107a6565b3480156102d057600080fd5b506102f87f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101c1565b34801561031957600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c1565b34801561036557600080fd5b5061022661037436600461304a565b6107c7565b34801561038557600080fd5b5061022661039436600461304a565b61083a565b3480156103a557600080fd5b5061011b5461033490640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103db57600080fd5b5061011b546102f89063ffffffff1681565b3480156103f957600080fd5b5061022661040836600461304a565b6108fa565b34801561041957600080fd5b5061011b54610444907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101c19190613096565b34801561045d57600080fd5b5061022661046c36600461304a565b6109a8565b34801561047d57600080fd5b5060b8546103349073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104aa57600080fd5b506104be6104b93660046130eb565b610b6a565b60405167ffffffffffffffff90911681526020016101c1565b3480156104e357600080fd5b5060b7546103349073ffffffffffffffffffffffffffffffffffffffff1681565b34801561051057600080fd5b506101b7610b8d565b34801561052557600080fd5b5061022661053436600461304a565b610b9e565b61022661054736600461311e565b610c97565b34801561055857600080fd5b506020546101b79081565b34801561056f57600080fd5b50610578600081565b60405160ff90911681526020016101c1565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff1660028111156105c2576105c2613067565b036106145760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061062084610f91565b9150915060006106358262ffffff19166110a1565b9050600061064862ffffff1984166110b5565b60215490915063ffffffff831610156106915760218263ffffffff1681548110610674576106746131ad565b906000526020600020015481036106915750600095945050505050565b6106996110ca565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106ca929190613256565b60405180910390a160019450505050505b919050565b6106e86110ca565b565b6021546000908190801561072c576107036001826132b4565b925060218363ffffffff168154811061071e5761071e6131ad565b906000526020600020015491505b509091565b6107396111e5565b61014b55565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b602181815481106107b657600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff16331461082e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b6108378161124c565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108aa5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161060b565b6108b381611334565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006109b460016113b3565b905080156109e957605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6109f28261124c565b610a8c61011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8791906132cb565b611507565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610b6657605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b600067ffffffff00000000602084901b1663ffffffff8316175b90505b92915050565b6000610b996000611595565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b73ffffffffffffffffffffffffffffffffffffffff8116610c8e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161060b565b610837816115a8565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610ccd57610ccd613067565b03610d1a5760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161060b565b61080081511115610d6d5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161060b565b34610d85610d7a8461161f565b62ffffff191661162c565b6bffffffffffffffffffffffff1614610de05760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161060b565b61011b54610df59063ffffffff1660016132e8565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e368561168e565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f008286866116ed565b80516020820120909150610f1381611768565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f4260205490565b610f4c91906132b4565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f7e929190613310565b60405180910390a4505050505050505050565b600080610f9e8382611798565b905060286bffffffffffffffffffffffff601883901c16116110025760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161060b565b61103661101462ffffff1983166117bc565b61103161102662ffffff1985166117d1565b62ffffff1916611804565b611857565b915061105061104a62ffffff1983166118d6565b836118ea565b61109c5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161060b565b915091565b6000610b8762ffffff19831660048061198b565b6000610b8762ffffff198316600860206119bb565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b15801561118457600080fd5b505af1158015611198573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106e85760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161060b565b73ffffffffffffffffffffffffffffffffffffffff81163b6112b05760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161060b565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610b5d565b605254600090610100900460ff1615611452578160ff1660011480156113d85750303b155b61144a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161060b565b506000919050565b60525460ff8084169116106114cf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161060b565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115845760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b61158c611b79565b61083781611334565b6000610b87826115a3611bfe565b6120bf565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610b87826002611798565b60008161164260025b62ffffff19831690612182565b5061164c83612283565b611655846122b1565b61165e856122d2565b611667866122f3565b6116719190613335565b61167b9190613335565b6116859190613335565b91505b50919050565b60007fffffffffffffffffffffffff000000000000000000000000000000000000000082146116be573392915050565b6116c66111e5565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906117016004600261335c565b60ff1661170e9190613385565b9050600084518261171f9190613385565b9050600161172f6004600261335c565b60ff16838389898960405160200161174d97969594939291906133a2565b604051602081830303815290604052925050505b9392505050565b611773600082612314565b602161177f6000611595565b8154600181018355600092835260209092209091015550565b8151600090602084016117b364ffffffffff85168284612437565b95945050505050565b6000610b8762ffffff1983168260288161247e565b6000610b8760286117f481601886901c6bffffffffffffffffffffffff166132b4565b62ffffff1985169190600061247e565b60606000806118218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506118468483602001612502565b508181016020016040529052919050565b60008061186962ffffff19851661269d565b90506118c2816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506118ce81846126fa565b949350505050565b6000610b8762ffffff19831682600461198b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119675760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161060b565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b6000611998826020613440565b6119a390600861335c565b60ff166119b18585856119bb565b901c949350505050565b60008160ff166000036119d057506000611761565b6119e88460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611a0360ff841685613463565b1115611a7b57611a62611a248560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611a4a8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661271e565b60405162461bcd60e51b815260040161060b919061347b565b60208260ff161115611af55760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161060b565b600882026000611b138660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611bf65760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b6106e861278c565b611c06612ee1565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561217a57600182821c811690819003612126578582602081106120f3576120f36131ad565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612171565b83858360208110612139576121396131ad565b6020020151604051602001612158929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016120c9565b505092915050565b600061218e8383612812565b61227c5760006121ad6121a18560d81c90565b64ffffffffff16612835565b91505060006121c28464ffffffffff16612835565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161060b919061347b565b5090919050565b6000816122906002611635565b506122a462ffffff1984166026600c61198b565b63ffffffff169392505050565b6000816122be6002611635565b506122a462ffffff198416601a600c61198b565b6000816122df6002611635565b506122a462ffffff198416600e600c61198b565b6000816123006002611635565b506122a462ffffff1984166002600c61198b565b602080830154906001906123299060026135a6565b61233391906132b4565b81106123815760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161060b565b6001016020830181905560005b602081101561242957816001166001036123bd57828482602081106123b5576123b56131ad565b015550505050565b8381602081106123cf576123cf6131ad565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161238e565b506124326135b2565b505050565b6000806124448385613463565b9050604051811115612454575060005b806000036124695762ffffff19915050611761565b5050606092831b9190911790911b1760181b90565b6000806124998660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506124b28661291f565b846124bd8784613463565b6124c79190613463565b11156124da5762ffffff199150506118ce565b6124e48582613463565b90506124f88364ffffffffff168286612437565b9695505050505050565b600062ffffff198084160361257f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161060b565b61258883612967565b6125fa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161060b565b60006126148460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061263e8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156126635760206060fd5b8285848460045afa506124f86126798760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806126b88360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126e28460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061270985856129a4565b9150915061271681612a12565b509392505050565b6060600061272b86612835565b915050600061273986612835565b915050600061274786612835565b915050600061275586612835565b9150508383838360405160200161276f94939291906135e1565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166128095760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b6106e8336115a8565b60008164ffffffffff166128268460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156128a857600061285482600861335c565b60ff1685901c905061286581612bfe565b61ffff16841793508160ff1660101461288057601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161283b565b50600f5b60ff8160ff1610156129195760006128c582600861335c565b60ff1685901c90506128d681612bfe565b61ffff16831792508160ff166000146128f157601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128ac565b50915091565b60006129398260181c6bffffffffffffffffffffffff1690565b6129518360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006129738260d81c90565b64ffffffffff1664ffffffffff0361298d57506000919050565b60006129988361291f565b60405110199392505050565b60008082516041036129da5760208301516040840151606085015160001a6129ce87828585612c30565b94509450505050612a0b565b8251604003612a0357602083015160408401516129f8868383612d48565b935093505050612a0b565b506000905060025b9250929050565b6000816004811115612a2657612a26613067565b03612a2e5750565b6001816004811115612a4257612a42613067565b03612a8f5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161060b565b6002816004811115612aa357612aa3613067565b03612af05760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161060b565b6003816004811115612b0457612b04613067565b03612b775760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161060b565b6004816004811115612b8b57612b8b613067565b036108375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161060b565b6000612c1060048360ff16901c612d9a565b60ff1661ffff919091161760081b612c2782612d9a565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c675750600090506003612d3f565b8460ff16601b14158015612c7f57508460ff16601c14155b15612c905750600090506004612d3f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612ce4573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612d3857600060019250925050612d3f565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612d7e60ff86901c601b613463565b9050612d8c87828885612c30565b935093505050935093915050565b600060f08083179060ff82169003612db55750603092915050565b8060ff1660f103612dc95750603192915050565b8060ff1660f203612ddd5750603292915050565b8060ff1660f303612df15750603392915050565b8060ff1660f403612e055750603492915050565b8060ff1660f503612e195750603592915050565b8060ff1660f603612e2d5750603692915050565b8060ff1660f703612e415750603792915050565b8060ff1660f803612e555750603892915050565b8060ff1660f903612e695750603992915050565b8060ff1660fa03612e7d5750606192915050565b8060ff1660fb03612e915750606292915050565b8060ff1660fc03612ea55750606392915050565b8060ff1660fd03612eb95750606492915050565b8060ff1660fe03612ecd5750606592915050565b8060ff1660ff036116885750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612f4057600080fd5b813567ffffffffffffffff80821115612f5b57612f5b612f00565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612fa157612fa1612f00565b81604052838152866020858801011115612fba57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612fec57600080fd5b813567ffffffffffffffff81111561300357600080fd5b6118ce84828501612f2f565b60006020828403121561302157600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461083757600080fd5b60006020828403121561305c57600080fd5b813561176181613028565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106130d1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106db57600080fd5b600080604083850312156130fe57600080fd5b613107836130d7565b9150613115602084016130d7565b90509250929050565b600080600080600060a0868803121561313657600080fd5b61313f866130d7565b945060208601359350613154604087016130d7565b9250606086013567ffffffffffffffff8082111561317157600080fd5b61317d89838a01612f2f565b9350608088013591508082111561319357600080fd5b506131a088828901612f2f565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156131f75781810151838201526020016131df565b83811115613206576000848401525b50505050565b600081518084526132248160208601602086016131dc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006118ce604083018461320c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156132c6576132c6613285565b500390565b6000602082840312156132dd57600080fd5b815161176181613028565b600063ffffffff80831681851680830382111561330757613307613285565b01949350505050565b604081526000613323604083018561320c565b82810360208401526117b3818561320c565b60006bffffffffffffffffffffffff80831681851680830382111561330757613307613285565b600060ff821660ff84168160ff048111821515161561337d5761337d613285565b029392505050565b600061ffff80831681851680830382111561330757613307613285565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134028160088501602089016131dc565b8451908301906134198160088401602089016131dc565b845191019061342f8160088401602088016131dc565b016008019998505050505050505050565b600060ff821660ff84168082101561345a5761345a613285565b90039392505050565b6000821982111561347657613476613285565b500190565b602081526000610b84602083018461320c565b600181815b808511156134e757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156134cd576134cd613285565b808516156134da57918102915b93841c9390800290613493565b509250929050565b6000826134fe57506001610b87565b8161350b57506000610b87565b8160018114613521576002811461352b57613547565b6001915050610b87565b60ff84111561353c5761353c613285565b50506001821b610b87565b5060208310610133831016604e8410600b841016171561356a575081810a610b87565b613574838361348e565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561337d5761337d613285565b6000610b8483836134ef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016124f856fea264697066735822122037ab8d40eb39e867f1417038e0c4eb81544094d7cb53a67fa3b48171a87ae08064736f6c634300080d0033","runtime-code":"0x6080604052600436106101a15760003560e01c80639df6c8e1116100e1578063da180e701161008a578063f2fde38b11610064578063f2fde38b14610519578063f7560e4014610539578063fd54b2281461054c578063ffa1ad741461056357600080fd5b8063da180e701461049e578063df034cd0146104d7578063ebf0c7171461050457600080fd5b8063c19d93fb116100bb578063c19d93fb1461040d578063c4d66de814610451578063ccbdf9c91461047157600080fd5b80639df6c8e114610399578063affed0e0146103cf578063b7bc563e146103ed57600080fd5b8063522ae0021161014e5780638d3638f4116101285780638d3638f4146102c45780638da5cb5b1461030d5780639776120e146103595780639d54f4191461037957600080fd5b8063522ae00214610279578063715018a61461028f5780637ea97f40146102a457600080fd5b8063146901db1161017f578063146901db1461021157806336e104de1461022857806348639d241461025957600080fd5b806306661abd146101a6578063089d2894146101ca5780630afe7f90146101e1575b600080fd5b3480156101b257600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101d657600080fd5b506101b761014b5481565b3480156101ed57600080fd5b506102016101fc366004612fda565b61058a565b60405190151581526020016101c1565b34801561021d57600080fd5b506102266106e0565b005b34801561023457600080fd5b5061023d6106ea565b6040805163ffffffff90931683526020830191909152016101c1565b34801561026557600080fd5b5061022661027436600461300f565b610731565b34801561028557600080fd5b506101b761080081565b34801561029b57600080fd5b5061022661073f565b3480156102b057600080fd5b506101b76102bf36600461300f565b6107a6565b3480156102d057600080fd5b506102f87f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101c1565b34801561031957600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c1565b34801561036557600080fd5b5061022661037436600461304a565b6107c7565b34801561038557600080fd5b5061022661039436600461304a565b61083a565b3480156103a557600080fd5b5061011b5461033490640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156103db57600080fd5b5061011b546102f89063ffffffff1681565b3480156103f957600080fd5b5061022661040836600461304a565b6108fa565b34801561041957600080fd5b5061011b54610444907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101c19190613096565b34801561045d57600080fd5b5061022661046c36600461304a565b6109a8565b34801561047d57600080fd5b5060b8546103349073ffffffffffffffffffffffffffffffffffffffff1681565b3480156104aa57600080fd5b506104be6104b93660046130eb565b610b6a565b60405167ffffffffffffffff90911681526020016101c1565b3480156104e357600080fd5b5060b7546103349073ffffffffffffffffffffffffffffffffffffffff1681565b34801561051057600080fd5b506101b7610b8d565b34801561052557600080fd5b5061022661053436600461304a565b610b9e565b61022661054736600461311e565b610c97565b34801561055857600080fd5b506020546101b79081565b34801561056f57600080fd5b50610578600081565b60405160ff90911681526020016101c1565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff1660028111156105c2576105c2613067565b036106145760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061062084610f91565b9150915060006106358262ffffff19166110a1565b9050600061064862ffffff1984166110b5565b60215490915063ffffffff831610156106915760218263ffffffff1681548110610674576106746131ad565b906000526020600020015481036106915750600095945050505050565b6106996110ca565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106ca929190613256565b60405180910390a160019450505050505b919050565b6106e86110ca565b565b6021546000908190801561072c576107036001826132b4565b925060218363ffffffff168154811061071e5761071e6131ad565b906000526020600020015491505b509091565b6107396111e5565b61014b55565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b602181815481106107b657600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff16331461082e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b6108378161124c565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108aa5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161060b565b6108b381611334565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006109b460016113b3565b905080156109e957605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6109f28261124c565b610a8c61011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a8791906132cb565b611507565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610b6657605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b600067ffffffff00000000602084901b1663ffffffff8316175b90505b92915050565b6000610b996000611595565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161060b565b73ffffffffffffffffffffffffffffffffffffffff8116610c8e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161060b565b610837816115a8565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610ccd57610ccd613067565b03610d1a5760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161060b565b61080081511115610d6d5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161060b565b34610d85610d7a8461161f565b62ffffff191661162c565b6bffffffffffffffffffffffff1614610de05760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161060b565b61011b54610df59063ffffffff1660016132e8565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e368561168e565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f008286866116ed565b80516020820120909150610f1381611768565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f4260205490565b610f4c91906132b4565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f7e929190613310565b60405180910390a4505050505050505050565b600080610f9e8382611798565b905060286bffffffffffffffffffffffff601883901c16116110025760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161060b565b61103661101462ffffff1983166117bc565b61103161102662ffffff1985166117d1565b62ffffff1916611804565b611857565b915061105061104a62ffffff1983166118d6565b836118ea565b61109c5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161060b565b915091565b6000610b8762ffffff19831660048061198b565b6000610b8762ffffff198316600860206119bb565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b15801561118457600080fd5b505af1158015611198573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106e85760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161060b565b73ffffffffffffffffffffffffffffffffffffffff81163b6112b05760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161060b565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610b5d565b605254600090610100900460ff1615611452578160ff1660011480156113d85750303b155b61144a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161060b565b506000919050565b60525460ff8084169116106114cf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161060b565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115845760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b61158c611b79565b61083781611334565b6000610b87826115a3611bfe565b6120bf565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610b87826002611798565b60008161164260025b62ffffff19831690612182565b5061164c83612283565b611655846122b1565b61165e856122d2565b611667866122f3565b6116719190613335565b61167b9190613335565b6116859190613335565b91505b50919050565b60007fffffffffffffffffffffffff000000000000000000000000000000000000000082146116be573392915050565b6116c66111e5565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906117016004600261335c565b60ff1661170e9190613385565b9050600084518261171f9190613385565b9050600161172f6004600261335c565b60ff16838389898960405160200161174d97969594939291906133a2565b604051602081830303815290604052925050505b9392505050565b611773600082612314565b602161177f6000611595565b8154600181018355600092835260209092209091015550565b8151600090602084016117b364ffffffffff85168284612437565b95945050505050565b6000610b8762ffffff1983168260288161247e565b6000610b8760286117f481601886901c6bffffffffffffffffffffffff166132b4565b62ffffff1985169190600061247e565b60606000806118218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506118468483602001612502565b508181016020016040529052919050565b60008061186962ffffff19851661269d565b90506118c2816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506118ce81846126fa565b949350505050565b6000610b8762ffffff19831682600461198b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119675760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161060b565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b6000611998826020613440565b6119a390600861335c565b60ff166119b18585856119bb565b901c949350505050565b60008160ff166000036119d057506000611761565b6119e88460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611a0360ff841685613463565b1115611a7b57611a62611a248560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611a4a8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661271e565b60405162461bcd60e51b815260040161060b919061347b565b60208260ff161115611af55760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161060b565b600882026000611b138660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611bf65760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b6106e861278c565b611c06612ee1565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561217a57600182821c811690819003612126578582602081106120f3576120f36131ad565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612171565b83858360208110612139576121396131ad565b6020020151604051602001612158929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016120c9565b505092915050565b600061218e8383612812565b61227c5760006121ad6121a18560d81c90565b64ffffffffff16612835565b91505060006121c28464ffffffffff16612835565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161060b919061347b565b5090919050565b6000816122906002611635565b506122a462ffffff1984166026600c61198b565b63ffffffff169392505050565b6000816122be6002611635565b506122a462ffffff198416601a600c61198b565b6000816122df6002611635565b506122a462ffffff198416600e600c61198b565b6000816123006002611635565b506122a462ffffff1984166002600c61198b565b602080830154906001906123299060026135a6565b61233391906132b4565b81106123815760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161060b565b6001016020830181905560005b602081101561242957816001166001036123bd57828482602081106123b5576123b56131ad565b015550505050565b8381602081106123cf576123cf6131ad565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161238e565b506124326135b2565b505050565b6000806124448385613463565b9050604051811115612454575060005b806000036124695762ffffff19915050611761565b5050606092831b9190911790911b1760181b90565b6000806124998660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506124b28661291f565b846124bd8784613463565b6124c79190613463565b11156124da5762ffffff199150506118ce565b6124e48582613463565b90506124f88364ffffffffff168286612437565b9695505050505050565b600062ffffff198084160361257f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161060b565b61258883612967565b6125fa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161060b565b60006126148460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061263e8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156126635760206060fd5b8285848460045afa506124f86126798760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806126b88360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126e28460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061270985856129a4565b9150915061271681612a12565b509392505050565b6060600061272b86612835565b915050600061273986612835565b915050600061274786612835565b915050600061275586612835565b9150508383838360405160200161276f94939291906135e1565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166128095760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161060b565b6106e8336115a8565b60008164ffffffffff166128268460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156128a857600061285482600861335c565b60ff1685901c905061286581612bfe565b61ffff16841793508160ff1660101461288057601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161283b565b50600f5b60ff8160ff1610156129195760006128c582600861335c565b60ff1685901c90506128d681612bfe565b61ffff16831792508160ff166000146128f157601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128ac565b50915091565b60006129398260181c6bffffffffffffffffffffffff1690565b6129518360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006129738260d81c90565b64ffffffffff1664ffffffffff0361298d57506000919050565b60006129988361291f565b60405110199392505050565b60008082516041036129da5760208301516040840151606085015160001a6129ce87828585612c30565b94509450505050612a0b565b8251604003612a0357602083015160408401516129f8868383612d48565b935093505050612a0b565b506000905060025b9250929050565b6000816004811115612a2657612a26613067565b03612a2e5750565b6001816004811115612a4257612a42613067565b03612a8f5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161060b565b6002816004811115612aa357612aa3613067565b03612af05760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161060b565b6003816004811115612b0457612b04613067565b03612b775760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161060b565b6004816004811115612b8b57612b8b613067565b036108375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161060b565b6000612c1060048360ff16901c612d9a565b60ff1661ffff919091161760081b612c2782612d9a565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c675750600090506003612d3f565b8460ff16601b14158015612c7f57508460ff16601c14155b15612c905750600090506004612d3f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612ce4573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612d3857600060019250925050612d3f565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612d7e60ff86901c601b613463565b9050612d8c87828885612c30565b935093505050935093915050565b600060f08083179060ff82169003612db55750603092915050565b8060ff1660f103612dc95750603192915050565b8060ff1660f203612ddd5750603292915050565b8060ff1660f303612df15750603392915050565b8060ff1660f403612e055750603492915050565b8060ff1660f503612e195750603592915050565b8060ff1660f603612e2d5750603692915050565b8060ff1660f703612e415750603792915050565b8060ff1660f803612e555750603892915050565b8060ff1660f903612e695750603992915050565b8060ff1660fa03612e7d5750606192915050565b8060ff1660fb03612e915750606292915050565b8060ff1660fc03612ea55750606392915050565b8060ff1660fd03612eb95750606492915050565b8060ff1660fe03612ecd5750606592915050565b8060ff1660ff036116885750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612f4057600080fd5b813567ffffffffffffffff80821115612f5b57612f5b612f00565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612fa157612fa1612f00565b81604052838152866020858801011115612fba57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612fec57600080fd5b813567ffffffffffffffff81111561300357600080fd5b6118ce84828501612f2f565b60006020828403121561302157600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461083757600080fd5b60006020828403121561305c57600080fd5b813561176181613028565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106130d1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106db57600080fd5b600080604083850312156130fe57600080fd5b613107836130d7565b9150613115602084016130d7565b90509250929050565b600080600080600060a0868803121561313657600080fd5b61313f866130d7565b945060208601359350613154604087016130d7565b9250606086013567ffffffffffffffff8082111561317157600080fd5b61317d89838a01612f2f565b9350608088013591508082111561319357600080fd5b506131a088828901612f2f565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156131f75781810151838201526020016131df565b83811115613206576000848401525b50505050565b600081518084526132248160208601602086016131dc565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006118ce604083018461320c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156132c6576132c6613285565b500390565b6000602082840312156132dd57600080fd5b815161176181613028565b600063ffffffff80831681851680830382111561330757613307613285565b01949350505050565b604081526000613323604083018561320c565b82810360208401526117b3818561320c565b60006bffffffffffffffffffffffff80831681851680830382111561330757613307613285565b600060ff821660ff84168160ff048111821515161561337d5761337d613285565b029392505050565b600061ffff80831681851680830382111561330757613307613285565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134028160088501602089016131dc565b8451908301906134198160088401602089016131dc565b845191019061342f8160088401602088016131dc565b016008019998505050505050505050565b600060ff821660ff84168082101561345a5761345a613285565b90039392505050565b6000821982111561347657613476613285565b500190565b602081526000610b84602083018461320c565b600181815b808511156134e757817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156134cd576134cd613285565b808516156134da57918102915b93841c9390800290613493565b509250929050565b6000826134fe57506001610b87565b8161350b57506000610b87565b8160018114613521576002811461352b57613547565b6001915050610b87565b60ff84111561353c5761353c613285565b50506001821b610b87565b5060208310610133831016604e8410600b841016171561356a575081810a610b87565b613574838361348e565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561337d5761337d613285565b6000610b8483836134ef565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016124f856fea264697066735822122037ab8d40eb39e867f1417038e0c4eb81544094d7cb53a67fa3b48171a87ae08064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"117527:465:0:-:0;;;117598:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71588:26;;;;117527:465;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;117527:465:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"117527:465:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96350:81;;;;;;;;;;-1:-1:-1;96414:10:0;;96350:81;;;160:25:1;;;148:2;133:18;96350:81:0;;;;;;;;117562:29;;;;;;;;;;;;;;;;113758:776;;;;;;;;;;-1:-1:-1;113758:776:0;;;;;:::i;:::-;;:::i;:::-;;;1657:14:1;;1650:22;1632:41;;1620:2;1605:18;113758:776:0;1492:187:1;117772:52:0;;;;;;;;;;;;;:::i;:::-;;112207:257;;;;;;;;;;;;;:::i;:::-;;;;1886:10:1;1874:23;;;1856:42;;1929:2;1914:18;;1907:34;;;;1829:18;112207:257:0;1684:263:1;117648:118:0;;;;;;;;;;-1:-1:-1;117648:118:0;;;;;:::i;:::-;;:::i;105811:58::-;;;;;;;;;;;;105860:9;105811:58;;72939:84;;;;;;;;;;;;;:::i;95894:32::-;;;;;;;;;;-1:-1:-1;95894:32:0;;;;;:::i;:::-;;:::i;70386:35::-;;;;;;;;;;;;;;;;;;2493:10:1;2481:23;;;2463:42;;2451:2;2436:18;70386:35:0;2319:192:1;68483:85:0;;;;;;;;;;-1:-1:-1;68555:6:0;;;;68483:85;;;2692:42:1;2680:55;;;2662:74;;2650:2;2635:18;68483:85:0;2516:226:1;109848:140:0;;;;;;;;;;-1:-1:-1;109848:140:0;;;;;:::i;:::-;;:::i;109209:220::-;;;;;;;;;;-1:-1:-1;109209:220:0;;;;;:::i;:::-;;:::i;106084:37::-;;;;;;;;;;-1:-1:-1;106084:37:0;;;;;;;;;;;105988:19;;;;;;;;;;-1:-1:-1;105988:19:0;;;;;;;;72137:133;;;;;;;;;;-1:-1:-1;72137:133:0;;;;;:::i;:::-;;:::i;106160:19::-;;;;;;;;;;-1:-1:-1;106160:19:0;;;;;;;;;;;;;;;;;;:::i;108115:394::-;;;;;;;;;;-1:-1:-1;108115:394:0;;;;;:::i;:::-;;:::i;70541:39::-;;;;;;;;;;-1:-1:-1;70541:39:0;;;;;;;;117830:160;;;;;;;;;;-1:-1:-1;117830:160:0;;;;;:::i;:::-;;:::i;:::-;;;5411:18:1;5399:31;;;5381:50;;5369:2;5354:18;117830:160:0;5237:200:1;70512:22:0;;;;;;;;;;-1:-1:-1;70512:22:0;;;;;;;;96166:81;;;;;;;;;;;;;:::i;69365:198::-;;;;;;;;;;-1:-1:-1;69365:198:0;;;;;:::i;:::-;;:::i;110494:1473::-;;;;;;:::i;:::-;;:::i;95862:26::-;;;;;;;;;;-1:-1:-1;95862:26:0;;;;;;50:33;;;;;;;;;;;;82:1;50:33;;;;;6372:4:1;6360:17;;;6342:36;;6330:2;6315:18;50:33:0;6200:184:1;113758:776:0;113840:4;108927:13;108918:5;;;;;;;:22;;;;;;;;:::i;:::-;;108910:47;;;;-1:-1:-1;;;108910:47:0;;6591:2:1;108910:47:0;;;6573:21:1;6630:2;6610:18;;;6603:30;6669:14;6649:18;;;6642:42;6701:18;;108910:47:0;;;;;;;;;113911:16:::1;113929:13:::0;113946:31:::1;113964:12;113946:17;:31::i;:::-;113910:67;;;;113987:13;114003:24;:5;:22;;;;:24::i;:::-;113987:40:::0;-1:-1:-1;114037:13:0::1;114053:23;-1:-1:-1::0;;114053:21:0;::::1;;:23::i;:::-;114161:15;:22:::0;114037:39;;-1:-1:-1;114152:31:0::1;::::0;::::1;;114148:284;;;114212:15;114228:6;114212:23;;;;;;;;;;:::i;:::-;;;;;;;;;114203:5;:32:::0;114199:139:::1;;-1:-1:-1::0;114318:5:0::1;::::0;113758:776;-1:-1:-1;;;;;113758:776:0:o;114199:139::-:1;114441:7;:5;:7::i;:::-;114463:43;114483:8;114493:12;114463:43;;;;;;;:::i;:::-;;;;;;;;114523:4;114516:11;;;;;;108967:1;113758:776:::0;;;:::o;117772:52::-;117810:7;:5;:7::i;:::-;117772:52::o;112207:257::-;112312:15;:22;112255:13;;;;112348:11;;112344:114;;112391:10;112400:1;112391:6;:10;:::i;:::-;112375:27;;112424:15;112440:6;112424:23;;;;;;;;;;:::i;:::-;;;;;;;;;112416:31;;112344:114;112285:179;112207:257;;:::o;117648:118::-;72034:24;:22;:24::i;:::-;117733:14:::1;:26:::0;117648:118::o;72939:84::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;8366:2:1;68687:68:0;;;8348:21:1;;;8385:18;;;8378:30;8444:34;8424:18;;;8417:62;8496:18;;68687:68:0;8164:356:1;95894:32:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;95894:32:0;:::o;109848:140::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;8366:2:1;68687:68:0;;;8348:21:1;;;8385:18;;;8378:30;8444:34;8424:18;;;8417:62;8496:18;;68687:68:0;8164:356:1;68687:68:0;109929:52:::1;109964:15;109929:18;:52::i;:::-;109848:140:::0;:::o;109209:220::-;108723:14;;;;;;;108701:10;:37;108693:65;;;;-1:-1:-1;;;108693:65:0;;8727:2:1;108693:65:0;;;8709:21:1;8766:2;8746:18;;;8739:30;8805:17;8785:18;;;8778:45;8840:18;;108693:65:0;8525:339:1;108693:65:0;109285:21:::1;109297:8;109285:11;:21::i;:::-;-1:-1:-1::0;109401:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;109209:220::o;72137:133::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;8366:2:1;68687:68:0;;;8348:21:1;;;8385:18;;;8378:30;8444:34;8424:18;;;8417:62;8496:18;;68687:68:0;8164:356:1;68687:68:0;72229:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;72137:133::o;108115:394::-;61379:19;61401:25;61424:1;61401:22;:25::i;:::-;61379:47;;61440:14;61436:65;;;61470:13;:20;;;;;;;;61436:65;108262:35:::1;108281:15;108262:18;:35::i;:::-;108307:50;108332:14;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108307;:50::i;:::-;108367:5;:21:::0;;;::::1;::::0;::::1;::::0;;108469:15:::1;:33:::0;;-1:-1:-1;108469:33:0;::::1;::::0;;-1:-1:-1;108469:33:0;;;;::::1;::::0;61521:99;;;;61555:13;:21;;;;;;61595:14;;-1:-1:-1;6342:36:1;;61595:14:0;;6330:2:1;6315:18;61595:14:0;;;;;;;;61521:99;61369:257;108115:394;:::o;117830:160::-;117916:6;115886:26;115910:2;115886:26;;;;115885:37;;;;117941:42;117934:49;;117830:160;;;;;:::o;96166:81::-;96203:7;96229:11;:4;:9;:11::i;:::-;96222:18;;96166:81;:::o;69365:198::-;68555:6;;68695:23;68555:6;67483:10;68695:23;68687:68;;;;-1:-1:-1;;;68687:68:0;;8366:2:1;68687:68:0;;;8348:21:1;;;8385:18;;;8378:30;8444:34;8424:18;;;8417:62;8496:18;;68687:68:0;8164:356:1;68687:68:0;69453:22:::1;::::0;::::1;69445:73;;;::::0;-1:-1:-1;;;69445:73:0;;9526:2:1;69445:73:0::1;::::0;::::1;9508:21:1::0;9565:2;9545:18;;;9538:30;9604:34;9584:18;;;9577:62;9675:8;9655:18;;;9648:36;9701:19;;69445:73:0::1;9324:402:1::0;69445:73:0::1;69528:28;69547:8;69528:18;:28::i;110494:1473::-:0;108927:13;108918:5;;;;;;;:22;;;;;;;;:::i;:::-;;108910:47;;;;-1:-1:-1;;;108910:47:0;;6591:2:1;108910:47:0;;;6573:21:1;6630:2;6610:18;;;6603:30;6669:14;6649:18;;;6642:42;6701:18;;108910:47:0;6389:336:1;108910:47:0;105860:9:::1;110731:12;:19;:45;;110723:70;;;::::0;-1:-1:-1;;;110723:70:0;;9933:2:1;110723:70:0::1;::::0;::::1;9915:21:1::0;9972:2;9952:18;;;9945:30;10011:14;9991:18;;;9984:42;10043:18;;110723:70:0::1;9731:336:1::0;110723:70:0::1;110843:9;110811:28;:16;:5;:14;:16::i;:::-;-1:-1:-1::0;;110811:26:0::1;;:28::i;:::-;:41;;;110803:59;;;::::0;-1:-1:-1;;;110803:59:0;;10274:2:1;110803:59:0::1;::::0;::::1;10256:21:1::0;10313:1;10293:18;;;10286:29;10351:7;10331:18;;;10324:35;10376:18;;110803:59:0::1;10072:328:1::0;110803:59:0::1;110956:5;::::0;:9:::1;::::0;:5:::1;;::::0;:9:::1;:::i;:::-;110948:5;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;110993:41:0::1;111016:17:::0;110993:22:::1;:41::i;:::-;111194:5;::::0;40462:242;;;14376:16:1;40462:242:0;;;14360:102:1;14481:66;111148:11:0::1;14584:3:1::0;14580:16;;;14576:25;;14563:11;;;14556:46;14618:11;;;14611:27;;;14672:16;;;;;14654:12;;;14647:47;14728:16;;;14724:25;;14710:12;;;14703:47;14766:12;;;14759:28;;;14821:16;;;;14817:25;;;14803:12;;;14796:47;40462:242:0;;;;;;;;;14859:12:1;;;;40462:242:0;;110975:59;;-1:-1:-1;111362:21:0::1;111386:51;111408:7;111417:5;111424:12;111386:21;:51::i;:::-;111528:19:::0;;::::1;::::0;::::1;::::0;111362:75;;-1:-1:-1;111610:25:0::1;111528:19:::0;111610:11:::1;:25::i;:::-;111903:5;::::0;::::1;;115910:2:::0;115886:26;;;;;115885:37;111789:171:::1;;111847:1;111837:7;96414:10:::0;;;96350:81;111837:7:::1;:11;;;;:::i;:::-;111811:12;111789:171;111923:5;111942:8;111789:171;;;;;;;:::i;:::-;;;;;;;;110713:1254;;;;110494:1473:::0;;;;;:::o;79047:474::-;79148:16;;79203:19;:12;79148:16;79203;:19::i;:::-;79195:27;-1:-1:-1;73720:2:0;3488:26;17310:2;17306:16;;;17302:28;74974:37;79232:52;;;;-1:-1:-1;;;79232:52:0;;11222:2:1;79232:52:0;;;11204:21:1;11261:2;11241:18;;;11234:30;11300:20;11280:18;;;11273:48;11338:18;;79232:52:0;11020:342:1;79232:52:0;79305:115;79337:23;-1:-1:-1;;79337:21:0;;;:23::i;:::-;79374:36;:28;-1:-1:-1;;79374:26:0;;;:28::i;:::-;-1:-1:-1;;79374:34:0;;:36::i;:::-;79305:18;:115::i;:::-;79294:126;-1:-1:-1;79438:47:0;79449:25;-1:-1:-1;;79449:23:0;;;:25::i;:::-;79476:8;79438:10;:47::i;:::-;79430:84;;;;-1:-1:-1;;;79430:84:0;;11569:2:1;79430:84:0;;;11551:21:1;11608:2;11588:18;;;11581:30;11647:26;11627:18;;;11620:54;11691:18;;79430:84:0;11367:348:1;79430:84:0;79047:474;;;:::o;75372:136::-;75436:6;75468:32;-1:-1:-1;;75468:15:0;;73614:1;;75468:15;:32::i;75601:124::-;75664:7;75690:28;-1:-1:-1;;75690:11:0;;73661:1;75715:2;75690:11;:28::i;115156:231::-;115226:5;:21;;;;;;;;;;;;115282:48;;;;;115318:10;115282:14;:48;;2662:74:1;115282:14:0;;;;;;;;;;:27;;2635:18:1;;115282:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;115360:7:0;;115345:35;;115369:10;;-1:-1:-1;115345:35:0;115360:7;;;;-1:-1:-1;115345:35:0;;115360:7;;115345:35;115156:231::o;72329:132::-;72417:15;;;;72395:10;:38;72387:67;;;;-1:-1:-1;;;72387:67:0;;12169:2:1;72387:67:0;;;12151:21:1;12208:2;12188:18;;;12181:30;12247:18;12227;;;12220:46;12283:18;;72387:67:0;11967:340:1;114708:285:0;98137:19;;;;114788:81;;;;-1:-1:-1;;;114788:81:0;;12514:2:1;114788:81:0;;;12496:21:1;12553:2;12533:18;;;12526:30;12592:26;12572:18;;;12565:54;12636:18;;114788:81:0;12312:348:1;114788:81:0;114879:14;:49;;;;;;;;;;;;;;;;;;114943:43;;2662:74:1;;;114943:43:0;;2650:2:1;2635:18;114943:43:0;;;;;;;114708:285;:::o;72567:179::-;72650:7;;;;72667:21;;;;;;;;;;;72703:36;;;72650:7;;;;12900:34:1;;;12965:2;12950:18;;12943:43;;;;72703:36:0;;12812:18:1;72703:36:0;12665:327:1;63555:808:0;63952:13;;63619:4;;63952:13;;;;;63948:409;;;64006:7;:12;;64017:1;64006:12;:61;;;;-1:-1:-1;64061:4:0;98137:19;:23;64006:61;63981:166;;;;-1:-1:-1;;;63981:166:0;;13199:2:1;63981:166:0;;;13181:21:1;13238:2;13218:18;;;13211:30;13277:34;13257:18;;;13250:62;13348:16;13328:18;;;13321:44;13382:19;;63981:166:0;12997:410:1;63981:166:0;-1:-1:-1;64168:5:0;;63555:808;-1:-1:-1;63555:808:0:o;63948:409::-;64212:12;;:22;;;;:12;;:22;64204:81;;;;-1:-1:-1;;;64204:81:0;;13199:2:1;64204:81:0;;;13181:21:1;13238:2;13218:18;;;13211:30;13277:34;13257:18;;;13250:62;13348:16;13328:18;;;13321:44;13382:19;;64204:81:0;12997:410:1;64204:81:0;-1:-1:-1;64299:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;63555:808:0:o;71673:142::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;13614:2:1;62958:69:0;;;13596:21:1;13653:2;13633:18;;;13626:30;13692:34;13672:18;;;13665:62;13763:13;13743:18;;;13736:41;13794:19;;62958:69:0;13412:407:1;62958:69:0;71761:16:::1;:14;:16::i;:::-;71787:21;71799:8;71787:11;:21::i;82634:122::-:0;82691:7;82717:32;82729:5;82736:12;:10;:12::i;:::-;82717:11;:32::i;69717:187::-;69809:6;;;;69825:17;;;;;;;;;;;69857:40;;69809:6;;;69825:17;69809:6;;69857:40;;69790:16;;69857:40;69780:124;69717:187;:::o;90222:122::-;90283:7;90309:28;:5;34906:10;90309:9;:28::i;91329:183::-;91402:6;91386:5;89229:35;34906:10;34899:18;-1:-1:-1;;89229:16:0;;;;:35::i;:::-;;91486:19:::1;91499:5;91486:12;:19::i;:::-;91467:16;91477:5;91467:9;:16::i;:::-;91447:17;91458:5;91447:10;:17::i;:::-;91427;91438:5;91427:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;91420:85;;89274:1;91329:183:::0;;;;:::o;116705:814::-;116811:14;92147:24;116845:48;;116841:672;;116945:10;116909:47;113758:776;-1:-1:-1;;113758:776:0:o;116841:672::-;117349:24;:22;:24::i;:::-;-1:-1:-1;92147:24:0;116705:814;;;:::o;36091:638::-;36387:14;;36236:12;;36344:17;;35842:29;35860:10;35713:1;35842:29;:::i;:::-;36364:13;;:38;;;;:::i;:::-;36344:58;;36412:17;36452:5;:12;36432:10;:33;;;;:::i;:::-;36412:53;-1:-1:-1;34563:1:0;35842:29;35860:10;35713:1;35842:29;:::i;:::-;36561:13;;36592:10;36620;36648:7;36673:5;36696:12;36494:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;36475:247;;;;36091:638;;;;;;:::o;96588:123::-;96643:18;:4;96655:5;96643:11;:18::i;:::-;96671:15;96692:11;:4;:9;:11::i;:::-;96671:33;;;;;;;-1:-1:-1;96671:33:0;;;;;;;;;;;-1:-1:-1;96588:123:0:o;14473:359::-;14577:10;;14543:7;;14724:4;14715:14;;14799:26;;;;14715:14;14577:10;14799:5;:26::i;:::-;14792:33;14473:359;-1:-1:-1;;;;;14473:359:0:o;75831:155::-;75894:7;75920:59;-1:-1:-1;;75920:11:0;;75894:7;73720:2;75894:7;75920:11;:59::i;76069:172::-;76137:7;76163:71;73720:2;76193:37;73720:2;17310;17306:16;;;3488:26;17302:28;76193:37;:::i;:::-;-1:-1:-1;;76163:11:0;;;:71;76232:1;76163:11;:71::i;29126:632::-;29181:16;29209:11;29230:12;29245;29249:7;17310:2;17306:16;3488:26;17302:28;;17064:282;29245:12;29230:27;;;;29367:4;29361:11;29354:18;;29422:3;29415:10;;29468:33;29481:7;29490:3;29496:4;29490:10;29468:12;:33::i;:::-;-1:-1:-1;29625:14:0;;;29641:4;29621:25;29615:4;29608:39;29688:17;;29126:632;;-1:-1:-1;29126:632:0:o;76568:285::-;76678:14;;76725;-1:-1:-1;;76725:12:0;;;:14::i;:::-;76708:31;;76758:36;76787:6;52303:58;;21781:66:1;52303:58:0;;;21769:79:1;21864:12;;;21857:28;;;52173:7:0;;21901:12:1;;52303:58:0;;;;;;;;;;;;52293:69;;;;;;52286:76;;52104:265;;;;76758:36;76749:45;;76813:33;76827:6;76835:10;76813:13;:33::i;:::-;76804:42;76568:285;-1:-1:-1;;;;76568:285:0:o;75115:143::-;75180:6;75212:38;-1:-1:-1;;75212:15:0;;75180:6;75248:1;75212:15;:38::i;115935:236::-;116057:4;116100:11;116085:26;;:11;:26;;;116077:51;;;;-1:-1:-1;;;116077:51:0;;16634:2:1;116077:51:0;;;16616:21:1;16673:2;16653:18;;;16646:30;16712:14;16692:18;;;16685:42;16744:18;;116077:51:0;16432:336:1;116077:51:0;-1:-1:-1;116157:7:0;;;;;;116145:19;;;;115935:236;-1:-1:-1;115935:236:0:o;21939:221::-;22058:14;22136:11;22141:6;22136:2;:11;:::i;:::-;22135:17;;22151:1;22135:17;:::i;:::-;22091:62;;22099:30;22105:7;22114:6;22122;22099:5;:30::i;:::-;22091:62;;;21939:221;-1:-1:-1;;;;21939:221:0:o;20822:771::-;20937:14;20967:6;:11;;20977:1;20967:11;20963:59;;-1:-1:-1;21009:1:0;20994:17;;20963:59;21053:12;21057:7;17310:2;17306:16;3488:26;17302:28;;17064:282;21053:12;21035:30;;:15;;;;:6;:15;:::i;:::-;:30;21031:137;;;21088:68;21104:12;21108:7;16204:3;16200:17;3488:26;16196:29;;15877:364;21104:12;21088:68;;21118:12;21122:7;17310:2;17306:16;3488:26;17302:28;;17064:282;21118:12;21088:68;;21132:6;21148;21140:15;;21088;:68::i;:::-;21081:76;;-1:-1:-1;;;21081:76:0;;;;;;;;:::i;21031:137::-;21195:2;21185:6;:12;;;;21177:83;;;;-1:-1:-1;;;21177:83:0;;17532:2:1;21177:83:0;;;17514:21:1;17571:2;17551:18;;;17544:30;17610:34;17590:18;;;17583:62;17681:28;17661:18;;;17654:56;17727:19;;21177:83:0;17330:422:1;21177:83:0;21341:1;21332:10;;21271:15;21377:12;21381:7;16204:3;16200:17;3488:26;16196:29;;15877:364;21377:12;21362:27;;;-1:-1:-1;21399:13:0;8306:66;8276:12;;;8255:131;21551:17;;;;21545:24;21541:36;;;-1:-1:-1;;;;;20822:771:0:o;68195:95::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;13614:2:1;62958:69:0;;;13596:21:1;13653:2;13633:18;;;13626:30;13692:34;13672:18;;;13665:62;13763:13;13743:18;;;13736:41;13794:19;;62958:69:0;13412:407:1;62958:69:0;68257:26:::1;:24;:26::i;82874:964::-:0;82919:34;;:::i;:::-;82978:3;82965:16;;83004:3;82965:10;82991;;:16;83030:3;83017:10;;;:16;83056:3;83043:10;;;:16;83082:3;83069:10;;;:16;83108:3;83095:10;;;:16;83134:3;83121:10;;;:16;83160:3;83147:10;;;:16;83186:3;83173:10;;;:16;83212:3;83199:10;;;:16;83239:4;83225:11;;;:18;83267:4;83253:11;;;:18;83295:4;83281:11;;;:18;83323:4;83309:11;;;:18;83351:4;83337:11;;;:18;83379:4;83365:11;;;:18;83407:4;83393:11;;;:18;83435:4;83421:11;;;:18;83463:4;83449:11;;;:18;83491:4;83477:11;;;:18;83519:4;83505:11;;;:18;83547:4;83533:11;;;:18;83575:4;83561:11;;;:18;83603:4;83589:11;;;:18;83631:4;83617:11;;;:18;83659:4;83645:11;;;:18;83687:4;83673:11;;;:18;83715:4;83701:11;;;:18;83743:4;83729:11;;;:18;83771:4;83757:11;;;:18;83799:4;83785:11;;;:18;83827:4;83813:11;;;:18;82965:7;82874:964::o;81978:589::-;82151:11;;;;82102:16;;;82173:388;80558:2;82193:1;:14;82173:388;;;82259:4;82244:11;;;82243:20;;;82281:12;;;82277:215;;82351:5;82364:1;82351:15;;;;;;;:::i;:::-;;;82334:43;;;;;;17914:19:1;;;;17949:12;;17942:28;;;17986:12;;82334:43:0;;;;;;;;;;;;82324:54;;;;;;82313:65;;82277:215;;;82455:8;82465:7;82473:1;82465:10;;;;;;;:::i;:::-;;;;;82438:38;;;;;;;;17914:19:1;;;17958:2;17949:12;;17942:28;17995:2;17986:12;;17757:247;82438:38:0;;;;;;;;;;;;;82428:49;;;;;;82417:60;;82277:215;-1:-1:-1;82533:3:0;;82173:388;;;;82124:443;81978:589;;;;:::o;10891:578::-;10969:7;10993:26;11000:7;11009:9;10993:6;:26::i;:::-;10988:451;;11038:9;11051:35;11069:15;11076:7;15235:3;15231:17;;15024:268;11069:15;11061:24;;11051:9;:35::i;:::-;11035:51;;;11103:9;11116:29;11134:9;11126:18;;11116:9;:29::i;:::-;11203:186;;18376:31:1;11203:186:0;;;18364:44:1;18427:66;18531:3;18527:16;;;18523:25;;18509:12;;;18502:47;18579:15;18565:12;;;18558:37;18629:16;;;18625:25;18611:12;;;18604:47;11100:45:0;;-1:-1:-1;11159:17:0;;-1:-1:-1;18667:12:1;;11203:186:0;;;;;;;;;;;;11159:244;;11424:3;11417:11;;-1:-1:-1;;;11417:11:0;;;;;;;;:::i;10988:451::-;-1:-1:-1;11455:7:0;;10891:578;-1:-1:-1;10891:578:0:o;91170:153::-;91246:6;91230:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;91278:37:0::1;-1:-1:-1::0;;91278:15:0;::::1;89177:2;91312;91278:15;:37::i;:::-;91264:52;;::::0;91170:153;-1:-1:-1;;;91170:153:0:o;90974:147::-;91047:6;91031:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;91079:34:0::1;-1:-1:-1::0;;91079:15:0;::::1;89124:2;91110;91079:15;:34::i;90779:149::-:0;90853:6;90837:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;90885:35:0::1;-1:-1:-1::0;;90885:15:0;::::1;89074:2;90917;90885:15;:35::i;90583:149::-:0;90657:6;90641:5;89229:35;34906:10;34899:18;;89229:35;-1:-1:-1;90689:35:0::1;-1:-1:-1::0;;90689:15:0;::::1;89024:1;90721:2;90689:15;:35::i;81017:750::-:0;81102:11;;;;;;80621:1;;80605:13;;:1;:13;:::i;:::-;:17;;;;:::i;:::-;81131:4;:17;81123:46;;;;-1:-1:-1;;;81123:46:0;;20386:2:1;81123:46:0;;;20368:21:1;20425:2;20405:18;;;20398:30;20464:18;20444;;;20437:46;20500:18;;81123:46:0;20184:340:1;81123:46:0;81204:6;;81230:11;;;:18;;;81263:9;81258:319;80558:2;81278:1;:14;81258:319;;;81315:4;81322:1;81315:8;81328:1;81314:15;81310:101;;81367:5;81349;81362:1;81349:15;;;;;;;:::i;:::-;;:23;-1:-1:-1;;;;81017:750:0:o;81310:101::-;81459:5;81472:1;81459:15;;;;;;;:::i;:::-;;;81442:40;;;;;;17914:19:1;;;;17949:12;;17942:28;;;17986:12;;81442:40:0;;;;;;;;;;;;;81432:51;;81442:40;81432:51;;;;;-1:-1:-1;81506:1:0;81497:10;;;;81549:3;81258:319;;;-1:-1:-1;81747:13:0;;:::i;:::-;81077:690;81017:750;;:::o;13614:462::-;13725:15;;13767:11;13774:4;13767;:11;:::i;:::-;13752:26;;13893:4;13887:11;13881:4;13878:21;13875:66;;;-1:-1:-1;13926:1:0;13875:66;13964:4;13972:1;13964:9;13960:51;;-1:-1:-1;;13989:11:0;;;;;13960:51;-1:-1:-1;;12883:2:0;12879:27;;;12953:17;;;;12945:26;;;13017:17;13013:2;13009:26;;13614:462::o;17947:399::-;18086:7;18105:12;18120;18124:7;16204:3;16200:17;3488:26;16196:29;;15877:364;18120:12;18105:27;;;;18216:12;18220:7;18216:3;:12::i;:::-;18209:4;18193:13;18200:6;18193:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;18189:77;;;-1:-1:-1;;18244:11:0;;;;;18189:77;18283:13;18290:6;18283:4;:13;:::i;:::-;18276:20;;18313:26;18319:7;18313:26;;18328:4;18334;18313:5;:26::i;:::-;18306:33;17947:399;-1:-1:-1;;;;;;17947:399:0:o;27854:902::-;27932:15;-1:-1:-1;;8790:15:0;;;;27959:69;;;;-1:-1:-1;;;27959:69:0;;20920:2:1;27959:69:0;;;20902:21:1;20959:2;20939:18;;;20932:30;20998:34;20978:18;;;20971:62;21069:10;21049:18;;;21042:38;21097:19;;27959:69:0;20718:404:1;27959:69:0;28046:16;28054:7;28046;:16::i;:::-;28038:72;;;;-1:-1:-1;;;28038:72:0;;21329:2:1;28038:72:0;;;21311:21:1;21368:2;21348:18;;;21341:30;21407:34;21387:18;;;21380:62;21478:13;21458:18;;;21451:41;21509:19;;28038:72:0;21127:407:1;28038:72:0;28120:12;28135;28139:7;17310:2;17306:16;3488:26;17302:28;;17064:282;28135:12;28120:27;;;;28157:15;28175:12;28179:7;16204:3;16200:17;3488:26;16196:29;;15877:364;28175:12;28157:30;;;;28198:11;28319:4;28313:11;28306:18;;28406:7;28401:3;28398:16;28395:94;;;28446:4;28440;28433:18;28395:94;28661:4;28652:7;28646:4;28637:7;28634:1;28627:5;28616:50;28612:55;28697:52;28718:15;28725:7;15235:3;15231:17;;15024:268;28718:15;12879:27;12883:2;12879:27;;;;12953:17;;12945:26;;13017:17;;13013:2;13009:26;;12629:446;23273:290;23329:14;23355:12;23370;23374:7;16204:3;16200:17;3488:26;16196:29;;15877:364;23370:12;23355:27;;;;23392:12;23407;23411:7;17310:2;17306:16;3488:26;17302:28;;17064:282;23407:12;23392:27;;23526:21;;;;23273:290;-1:-1:-1;;;23273:290:0:o;48400:227::-;48478:7;48498:17;48517:18;48539:27;48550:4;48556:9;48539:10;:27::i;:::-;48497:69;;;;48576:18;48588:5;48576:11;:18::i;:::-;-1:-1:-1;48611:9:0;48400:227;-1:-1:-1;;;48400:227:0:o;19579:741::-;19725:17;19757:9;19770:15;19780:4;19770:9;:15::i;:::-;19754:31;;;19798:9;19811:15;19821:4;19811:9;:15::i;:::-;19795:31;;;19839:9;19852:17;19862:6;19852:9;:17::i;:::-;19836:33;;;19882:9;19895:17;19905:6;19895:9;:17::i;:::-;19879:33;;;20062:1;20124;20204;20266;19948:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19922:391;;19744:576;;;;19579:741;;;;;;:::o;68296:111::-;62966:13;;;;;;;62958:69;;;;-1:-1:-1;;;62958:69:0;;13614:2:1;62958:69:0;;;13596:21:1;13653:2;13633:18;;;13626:30;13692:34;13672:18;;;13665:62;13763:13;13743:18;;;13736:41;13794:19;;62958:69:0;13412:407:1;62958:69:0;68368:32:::1;67483:10:::0;68368:18:::1;:32::i;10461:132::-:0;10535:4;10577:9;10558:28;;:15;10565:7;15235:3;15231:17;;15024:268;10558:15;:28;;;;10461:132;-1:-1:-1;;;10461:132:0:o;5849:667::-;5903:13;;5959:2;5944:258;5967:2;5963:1;:6;;;5944:258;;;5987:11;6014:5;:1;6018;6014:5;:::i;:::-;6007:13;;:2;:13;;5987:34;;6044:14;6052:5;6044:7;:14::i;:::-;6035:23;;;;;;6076:1;:7;;6081:2;6076:7;6072:58;;6113:2;6103:12;;;;;6072:58;-1:-1:-1;6171:6:0;;5944:258;;;-1:-1:-1;6265:2:0;6250:260;6273:3;6269:1;:7;;;6250:260;;;6294:11;6321:5;:1;6325;6321:5;:::i;:::-;6314:13;;:2;:13;;6294:34;;6352:14;6360:5;6352:7;:14::i;:::-;6342:24;;;;;;6384:1;:6;;6389:1;6384:6;6380:58;;6421:2;6410:13;;;;;6380:58;-1:-1:-1;6479:6:0;;6250:260;;;;5849:667;;;:::o;17520:147::-;17573:7;17638:12;17642:7;17310:2;17306:16;3488:26;17302:28;;17064:282;17638:12;17623;17627:7;16204:3;16200:17;3488:26;16196:29;;15877:364;17623:12;:27;17616:34;;;;17520:147;;;:::o;9463:333::-;9520:8;9544:15;9551:7;15235:3;15231:17;;15024:268;9544:15;:31;;9563:12;9544:31;9540:74;;-1:-1:-1;9598:5:0;;9463:333;-1:-1:-1;9463:333:0:o;9540:74::-;9623:12;9638;9642:7;9638:3;:12::i;:::-;9773:4;9767:11;-1:-1:-1;9754:26:0;;9463:333;-1:-1:-1;;;9463:333:0:o;46335:1279::-;46416:7;46425:12;46646:9;:16;46666:2;46646:22;46642:966;;46935:4;46920:20;;46914:27;46984:4;46969:20;;46963:27;47041:4;47026:20;;47020:27;46684:9;47012:36;47082:25;47093:4;47012:36;46914:27;46963;47082:10;:25::i;:::-;47075:32;;;;;;;;;46642:966;47128:9;:16;47148:2;47128:22;47124:484;;47397:4;47382:20;;47376:27;47447:4;47432:20;;47426:27;47487:23;47498:4;47376:27;47426;47487:10;:23::i;:::-;47480:30;;;;;;;;47124:484;-1:-1:-1;47557:1:0;;-1:-1:-1;47561:35:0;47124:484;46335:1279;;;;;:::o;44640:631::-;44717:20;44708:5;:29;;;;;;;;:::i;:::-;;44704:561;;44640:631;:::o;44704:561::-;44813:29;44804:5;:38;;;;;;;;:::i;:::-;;44800:465;;44858:34;;-1:-1:-1;;;44858:34:0;;23641:2:1;44858:34:0;;;23623:21:1;23680:2;23660:18;;;23653:30;23719:26;23699:18;;;23692:54;23763:18;;44858:34:0;23439:348:1;44800:465:0;44922:35;44913:5;:44;;;;;;;;:::i;:::-;;44909:356;;44973:41;;-1:-1:-1;;;44973:41:0;;23994:2:1;44973:41:0;;;23976:21:1;24033:2;24013:18;;;24006:30;24072:33;24052:18;;;24045:61;24123:18;;44973:41:0;23792:355:1;44909:356:0;45044:30;45035:5;:39;;;;;;;;:::i;:::-;;45031:234;;45090:44;;-1:-1:-1;;;45090:44:0;;24354:2:1;45090:44:0;;;24336:21:1;24393:2;24373:18;;;24366:30;24432:34;24412:18;;;24405:62;24503:4;24483:18;;;24476:32;24525:19;;45090:44:0;24152:398:1;45031:234:0;45164:30;45155:5;:39;;;;;;;;:::i;:::-;;45151:114;;45210:44;;-1:-1:-1;;;45210:44:0;;24757:2:1;45210:44:0;;;24739:21:1;24796:2;24776:18;;;24769:30;24835:34;24815:18;;;24808:62;24906:4;24886:18;;;24879:32;24928:19;;45210:44:0;24555:398:1;5326:199:0;5376:14;5413:18;5429:1;5423:2;:7;;;;5413:9;:18::i;:::-;5402:29;;5455:13;;;;;;5467:1;5455:13;5489;5499:2;5489:9;:13::i;:::-;5478:24;;;;5326:199;-1:-1:-1;5326:199:0:o;49808:1603::-;49934:7;;50858:66;50845:79;;50841:161;;;-1:-1:-1;50956:1:0;;-1:-1:-1;50960:30:0;50940:51;;50841:161;51015:1;:7;;51020:2;51015:7;;:18;;;;;51026:1;:7;;51031:2;51026:7;;51015:18;51011:100;;;-1:-1:-1;51065:1:0;;-1:-1:-1;51069:30:0;51049:51;;51011:100;51222:24;;;51205:14;51222:24;;;;;;;;;25185:25:1;;;25258:4;25246:17;;25226:18;;;25219:45;;;;25280:18;;;25273:34;;;25323:18;;;25316:34;;;51222:24:0;;25157:19:1;;51222:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51222:24:0;;;;;;-1:-1:-1;;51260:20:0;;;51256:101;;51312:1;51316:29;51296:50;;;;;;;51256:101;51375:6;-1:-1:-1;51383:20:0;;-1:-1:-1;49808:1603:0;;;;;;;;:::o;48881:336::-;48991:7;;49049:66;49036:80;;48991:7;49142:25;49158:3;49143:18;;;49165:2;49142:25;:::i;:::-;49126:42;;49185:25;49196:4;49202:1;49205;49208;49185:10;:25::i;:::-;49178:32;;;;;;48881:336;;;;;;:::o;3761:1393::-;3813:10;3979:4;3974:9;;;;4025:15;;;;;4021:57;;-1:-1:-1;4063:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4021:57::-;4096:7;:15;;4107:4;4096:15;4092:57;;-1:-1:-1;4134:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4092:57::-;4167:7;:15;;4178:4;4167:15;4163:57;;-1:-1:-1;4205:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4163:57::-;4238:7;:15;;4249:4;4238:15;4234:57;;-1:-1:-1;4276:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4234:57::-;4309:7;:15;;4320:4;4309:15;4305:57;;-1:-1:-1;4347:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4305:57::-;4380:7;:15;;4391:4;4380:15;4376:57;;-1:-1:-1;4418:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4376:57::-;4451:7;:15;;4462:4;4451:15;4447:57;;-1:-1:-1;4489:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4447:57::-;4522:7;:15;;4533:4;4522:15;4518:57;;-1:-1:-1;4560:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4518:57::-;4593:7;:15;;4604:4;4593:15;4589:57;;-1:-1:-1;4631:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4589:57::-;4664:7;:15;;4675:4;4664:15;4660:57;;-1:-1:-1;4702:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4660:57::-;4735:7;:15;;4746:4;4735:15;4731:57;;-1:-1:-1;4773:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4731:57::-;4806:7;:15;;4817:4;4806:15;4802:57;;-1:-1:-1;4844:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4802:57::-;4877:7;:15;;4888:4;4877:15;4873:57;;-1:-1:-1;4915:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4873:57::-;4948:7;:15;;4959:4;4948:15;4944:57;;-1:-1:-1;4986:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;4944:57::-;5019:7;:15;;5030:4;5019:15;5015:57;;-1:-1:-1;5057:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;5015:57::-;5090:7;:15;;5101:4;5090:15;5086:57;;-1:-1:-1;5128:4:0;;3761:1393;-1:-1:-1;;3761:1393:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:184:1:-;248:77;245:1;238:88;345:4;342:1;335:15;369:4;366:1;359:15;385:777;427:5;480:3;473:4;465:6;461:17;457:27;447:55;;498:1;495;488:12;447:55;534:6;521:20;560:18;597:2;593;590:10;587:36;;;603:18;;:::i;:::-;737:2;731:9;799:4;791:13;;642:66;787:22;;;811:2;783:31;779:40;767:53;;;835:18;;;855:22;;;832:46;829:72;;;881:18;;:::i;:::-;921:10;917:2;910:22;956:2;948:6;941:18;1002:3;995:4;990:2;982:6;978:15;974:26;971:35;968:55;;;1019:1;1016;1009:12;968:55;1083:2;1076:4;1068:6;1064:17;1057:4;1049:6;1045:17;1032:54;1130:1;1123:4;1118:2;1110:6;1106:15;1102:26;1095:37;1150:6;1141:15;;;;;;385:777;;;;:::o;1167:320::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;1344:9;1331:23;1377:18;1369:6;1366:30;1363:50;;;1409:1;1406;1399:12;1363:50;1432:49;1473:7;1464:6;1453:9;1449:22;1432:49;:::i;1952:180::-;2011:6;2064:2;2052:9;2043:7;2039:23;2035:32;2032:52;;;2080:1;2077;2070:12;2032:52;-1:-1:-1;2103:23:1;;1952:180;-1:-1:-1;1952:180:1:o;2747:154::-;2833:42;2826:5;2822:54;2815:5;2812:65;2802:93;;2891:1;2888;2881:12;2906:247;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3073:9;3060:23;3092:31;3117:5;3092:31;:::i;3688:184::-;3740:77;3737:1;3730:88;3837:4;3834:1;3827:15;3861:4;3858:1;3851:15;3877:396;4020:2;4005:18;;4053:1;4042:13;;4032:201;;4089:77;4086:1;4079:88;4190:4;4187:1;4180:15;4218:4;4215:1;4208:15;4032:201;4242:25;;;3877:396;:::o;4808:163::-;4875:20;;4935:10;4924:22;;4914:33;;4904:61;;4961:1;4958;4951:12;4976:256;5042:6;5050;5103:2;5091:9;5082:7;5078:23;5074:32;5071:52;;;5119:1;5116;5109:12;5071:52;5142:28;5160:9;5142:28;:::i;:::-;5132:38;;5189:37;5222:2;5211:9;5207:18;5189:37;:::i;:::-;5179:47;;4976:256;;;;;:::o;5442:753::-;5553:6;5561;5569;5577;5585;5638:3;5626:9;5617:7;5613:23;5609:33;5606:53;;;5655:1;5652;5645:12;5606:53;5678:28;5696:9;5678:28;:::i;:::-;5668:38;;5753:2;5742:9;5738:18;5725:32;5715:42;;5776:37;5809:2;5798:9;5794:18;5776:37;:::i;:::-;5766:47;;5864:2;5853:9;5849:18;5836:32;5887:18;5928:2;5920:6;5917:14;5914:34;;;5944:1;5941;5934:12;5914:34;5967:49;6008:7;5999:6;5988:9;5984:22;5967:49;:::i;:::-;5957:59;;6069:3;6058:9;6054:19;6041:33;6025:49;;6099:2;6089:8;6086:16;6083:36;;;6115:1;6112;6105:12;6083:36;;6138:51;6181:7;6170:8;6159:9;6155:24;6138:51;:::i;:::-;6128:61;;;5442:753;;;;;;;;:::o;6730:184::-;6782:77;6779:1;6772:88;6879:4;6876:1;6869:15;6903:4;6900:1;6893:15;6919:258;6991:1;7001:113;7015:6;7012:1;7009:13;7001:113;;;7091:11;;;7085:18;7072:11;;;7065:39;7037:2;7030:10;7001:113;;;7132:6;7129:1;7126:13;7123:48;;;7167:1;7158:6;7153:3;7149:16;7142:27;7123:48;;6919:258;;;:::o;7182:316::-;7223:3;7261:5;7255:12;7288:6;7283:3;7276:19;7304:63;7360:6;7353:4;7348:3;7344:14;7337:4;7330:5;7326:16;7304:63;:::i;:::-;7412:2;7400:15;7417:66;7396:88;7387:98;;;;7487:4;7383:109;;7182:316;-1:-1:-1;;7182:316:1:o;7503:337::-;7690:42;7682:6;7678:55;7667:9;7660:74;7770:2;7765;7754:9;7750:18;7743:30;7641:4;7790:44;7830:2;7819:9;7815:18;7807:6;7790:44;:::i;7845:184::-;7897:77;7894:1;7887:88;7994:4;7991:1;7984:15;8018:4;8015:1;8008:15;8034:125;8074:4;8102:1;8099;8096:8;8093:34;;;8107:18;;:::i;:::-;-1:-1:-1;8144:9:1;;8034:125::o;8869:251::-;8939:6;8992:2;8980:9;8971:7;8967:23;8963:32;8960:52;;;9008:1;9005;8998:12;8960:52;9040:9;9034:16;9059:31;9084:5;9059:31;:::i;10405:228::-;10444:3;10472:10;10509:2;10506:1;10502:10;10539:2;10536:1;10532:10;10570:3;10566:2;10562:12;10557:3;10554:21;10551:47;;;10578:18;;:::i;:::-;10614:13;;10405:228;-1:-1:-1;;;;10405:228:1:o;10638:377::-;10831:2;10820:9;10813:21;10794:4;10857:44;10897:2;10886:9;10882:18;10874:6;10857:44;:::i;:::-;10949:9;10941:6;10937:22;10932:2;10921:9;10917:18;10910:50;10977:32;11002:6;10994;10977:32;:::i;13824:244::-;13863:3;13891:26;13944:2;13941:1;13937:10;13974:2;13971:1;13967:10;14005:3;14001:2;13997:12;13992:3;13989:21;13986:47;;;14013:18;;:::i;14882:238::-;14920:7;14960:4;14957:1;14953:12;14992:4;14989:1;14985:12;15052:3;15046:4;15042:14;15037:3;15034:23;15027:3;15020:11;15013:19;15009:49;15006:75;;;15061:18;;:::i;:::-;15101:13;;14882:238;-1:-1:-1;;;14882:238:1:o;15125:224::-;15164:3;15192:6;15225:2;15222:1;15218:10;15255:2;15252:1;15248:10;15286:3;15282:2;15278:12;15273:3;15270:21;15267:47;;;15294:18;;:::i;15354:1073::-;15679:3;15707:66;15816:2;15807:6;15802:3;15798:16;15794:25;15789:3;15782:38;15871:2;15862:6;15857:3;15853:16;15849:25;15845:1;15840:3;15836:11;15829:46;15926:2;15917:6;15912:3;15908:16;15904:25;15900:1;15895:3;15891:11;15884:46;15981:2;15972:6;15967:3;15963:16;15959:25;15955:1;15950:3;15946:11;15939:46;;16014:6;16008:13;16030:61;16084:6;16080:1;16075:3;16071:11;16064:4;16056:6;16052:17;16030:61;:::i;:::-;16151:13;;16110:16;;;;16173:62;16151:13;16222:1;16214:10;;16207:4;16195:17;;16173:62;:::i;:::-;16296:13;;16254:17;;;16318:62;16296:13;16367:1;16359:10;;16352:4;16340:17;;16318:62;:::i;:::-;16400:17;16419:1;16396:25;;15354:1073;-1:-1:-1;;;;;;;;;15354:1073:1:o;16773:195::-;16811:4;16848;16845:1;16841:12;16880:4;16877:1;16873:12;16905:3;16900;16897:12;16894:38;;;16912:18;;:::i;:::-;16949:13;;;16773:195;-1:-1:-1;;;16773:195:1:o;16973:128::-;17013:3;17044:1;17040:6;17037:1;17034:13;17031:39;;;17050:18;;:::i;:::-;-1:-1:-1;17086:9:1;;16973:128::o;17106:219::-;17255:2;17244:9;17237:21;17218:4;17275:44;17315:2;17304:9;17300:18;17292:6;17275:44;:::i;18690:482::-;18779:1;18822:5;18779:1;18836:330;18857:7;18847:8;18844:21;18836:330;;;18976:4;18908:66;18904:77;18898:4;18895:87;18892:113;;;18985:18;;:::i;:::-;19035:7;19025:8;19021:22;19018:55;;;19055:16;;;;19018:55;19134:22;;;;19094:15;;;;18836:330;;;18840:3;18690:482;;;;;:::o;19177:866::-;19226:5;19256:8;19246:80;;-1:-1:-1;19297:1:1;19311:5;;19246:80;19345:4;19335:76;;-1:-1:-1;19382:1:1;19396:5;;19335:76;19427:4;19445:1;19440:59;;;;19513:1;19508:130;;;;19420:218;;19440:59;19470:1;19461:10;;19484:5;;;19508:130;19545:3;19535:8;19532:17;19529:43;;;19552:18;;:::i;:::-;-1:-1:-1;;19608:1:1;19594:16;;19623:5;;19420:218;;19722:2;19712:8;19709:16;19703:3;19697:4;19694:13;19690:36;19684:2;19674:8;19671:16;19666:2;19660:4;19657:12;19653:35;19650:77;19647:159;;;-1:-1:-1;19759:19:1;;;19791:5;;19647:159;19838:34;19863:8;19857:4;19838:34;:::i;:::-;19968:6;19900:66;19896:79;19887:7;19884:92;19881:118;;;19979:18;;:::i;20048:131::-;20108:5;20137:36;20164:8;20158:4;20137:36;:::i;20529:184::-;20581:77;20578:1;20571:88;20678:4;20675:1;20668:15;20702:4;20699:1;20692:15;22043:1391;22765:34;22753:47;;22830:23;22825:2;22816:12;;22809:45;22873:66;22977:3;22973:16;;;22969:25;;22964:2;22955:12;;22948:47;23014:17;23056:2;23047:12;;23040:24;;;23098:16;;;23094:25;;23089:2;23080:12;;23073:47;23150:34;23145:2;23136:12;;23129:56;23216:3;23210;23201:13;;23194:26;23255:16;;;23251:25;;23245:3;23236:13;;23229:48;23302:3;23293:13;;23286:25;23346:16;;;23342:25;23336:3;23327:13;;23320:48;22001:3;23423;23414:13;;21989:16;-1:-1:-1;22021:11:1;;;23384:44;21924:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"leafIndex","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"destinationAndNonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"tips","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Dispatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"ImproperAttestation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updaterManager","type":"address"}],"name":"NewUpdaterManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"address","name":"reporter","type":"address"}],"name":"UpdaterSlashed","type":"event"},{"inputs":[],"name":"MAX_MESSAGE_BODY_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destination","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"}],"name":"destinationAndNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipientAddress","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"improperAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUpdaterManager","name":"_updaterManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sensitiveValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"setFailed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newValue","type":"uint256"}],"name":"setSensitiveValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterManager","type":"address"}],"name":"setUpdaterManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Home.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"suggestUpdate","outputs":[{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updaterManager","outputs":[{"internalType":"contract IUpdaterManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"notice":"Emitted when a new message is dispatched via Nomad"},"ImproperAttestation(address,bytes)":{"notice":"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state"},"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"NewUpdaterManager(address)":{"notice":"Emitted when the UpdaterManager contract is changed"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"},"UpdaterSlashed(address,address)":{"notice":"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)"}},"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"notice":"Dispatch the message to the destination domain \u0026 recipient"},"improperAttestation(bytes)":{"notice":"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation."},"root()":{"notice":"Calculates and returns tree's current root"},"setUpdater(address)":{"notice":"Set a new Updater"},"setUpdaterManager(address)":{"notice":"Set a new UpdaterManager contract"},"suggestUpdate()":{"notice":"Suggest an update for the Updater to sign and submit."}},"version":1},"developerDoc":{"kind":"dev","methods":{"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"details":"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.","params":{"_destinationDomain":"Domain of destination chain","_messageBody":"Raw bytes content of message","_recipientAddress":"Address of recipient on destination chain as bytes32"}},"improperAttestation(bytes)":{"details":"Reverts (and doesn't slash updater) if signature is invalid or update not current","params":{"_attestation":"Attestation data and signature"},"returns":{"_0":"TRUE if update was an Improper Attestation (implying Updater was slashed)"}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setUpdater(address)":{"details":"To be set when rotating Updater after Fraud","params":{"_updater":"the new Updater"}},"setUpdaterManager(address)":{"details":"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation","params":{"_updaterManager":"the new UpdaterManager contract"}},"suggestUpdate()":{"details":"If no messages have been sent, null bytes returned for both","returns":{"_nonce":"Current nonce","_root":"Current merkle root"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destination\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"}],\"name\":\"destinationAndNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sensitiveValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"setFailed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newValue\",\"type\":\"uint256\"}],\"name\":\"setSensitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum Home.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"details\":\"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.\",\"params\":{\"_destinationDomain\":\"Domain of destination chain\",\"_messageBody\":\"Raw bytes content of message\",\"_recipientAddress\":\"Address of recipient on destination chain as bytes32\"}},\"improperAttestation(bytes)\":{\"details\":\"Reverts (and doesn't slash updater) if signature is invalid or update not current\",\"params\":{\"_attestation\":\"Attestation data and signature\"},\"returns\":{\"_0\":\"TRUE if update was an Improper Attestation (implying Updater was slashed)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setUpdater(address)\":{\"details\":\"To be set when rotating Updater after Fraud\",\"params\":{\"_updater\":\"the new Updater\"}},\"setUpdaterManager(address)\":{\"details\":\"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\",\"params\":{\"_updaterManager\":\"the new UpdaterManager contract\"}},\"suggestUpdate()\":{\"details\":\"If no messages have been sent, null bytes returned for both\",\"returns\":{\"_nonce\":\"Current nonce\",\"_root\":\"Current merkle root\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"notice\":\"Emitted when a new message is dispatched via Nomad\"},\"ImproperAttestation(address,bytes)\":{\"notice\":\"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state\"},\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"NewUpdaterManager(address)\":{\"notice\":\"Emitted when the UpdaterManager contract is changed\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"},\"UpdaterSlashed(address,address)\":{\"notice\":\"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)\"}},\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Dispatch the message to the destination domain \u0026 recipient\"},\"improperAttestation(bytes)\":{\"notice\":\"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation.\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"},\"setUpdater(address)\":{\"notice\":\"Set a new Updater\"},\"setUpdaterManager(address)\":{\"notice\":\"Set a new UpdaterManager contract\"},\"suggestUpdate()\":{\"notice\":\"Suggest an update for the Updater to sign and submit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"HomeHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"MAX_MESSAGE_BODY_BYTES()":"522ae002","VERSION()":"ffa1ad74","count()":"06661abd","destinationAndNonce(uint32,uint32)":"da180e70","dispatch(uint32,bytes32,uint32,bytes,bytes)":"f7560e40","historicalRoots(uint256)":"7ea97f40","improperAttestation(bytes)":"0afe7f90","initialize(address)":"c4d66de8","localDomain()":"8d3638f4","nonce()":"affed0e0","owner()":"8da5cb5b","renounceOwnership()":"715018a6","root()":"ebf0c717","sensitiveValue()":"089d2894","setFailed()":"146901db","setSensitiveValue(uint256)":"48639d24","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","setUpdaterManager(address)":"9776120e","state()":"c19d93fb","suggestUpdate()":"36e104de","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","tree()":"fd54b228","updater()":"df034cd0","updaterManager()":"9df6c8e1"}},"solidity/HomeHarness.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/HomeHarness.sol:IUpdaterManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"address payable","name":"_reporter","type":"address"}],"name":"slashUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"IUpdaterManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"slashUpdater(address)":"5b3c2cbf","updater()":"df034cd0"}},"solidity/HomeHarness.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122071d0a88a74163b9ea5ce5f06f2b61a24f8f2f2e3594e5870172cb9f9326aa9cd64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122071d0a88a74163b9ea5ce5f06f2b61a24f8f2f2e3594e5870172cb9f9326aa9cd64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80495:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;80495:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"80495:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:MerkleTreeManager":{"code":"0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212209c9021ddf69086cc54a59051cec9059651ff5909bff79db72268369753fd9de864736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212209c9021ddf69086cc54a59051cec9059651ff5909bff79db72268369753fd9de864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"95745:968:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"95745:968:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96350:81;96414:10;;96350:81;;;160:25:1;;;148:2;133:18;96350:81:0;;;;;;;95894:32;;;;;;:::i;:::-;;:::i;96166:81::-;;;:::i;95862:26::-;;;;;;;95894:32;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;95894:32:0;:::o;96166:81::-;96203:7;96229:11;:4;:9;:11::i;:::-;96222:18;;96166:81;:::o;82634:122::-;82691:7;82717:32;82729:5;82736:12;:10;:12::i;:::-;82717:11;:32::i;:::-;82710:39;82634:122;-1:-1:-1;;82634:122:0:o;82874:964::-;82919:34;;:::i;:::-;82978:3;82965:16;;83004:3;82965:10;82991;;:16;83030:3;83017:10;;;:16;83056:3;83043:10;;;:16;83082:3;83069:10;;;:16;83108:3;83095:10;;;:16;83134:3;83121:10;;;:16;83160:3;83147:10;;;:16;83186:3;83173:10;;;:16;83212:3;83199:10;;;:16;83239:4;83225:11;;;:18;83267:4;83253:11;;;:18;83295:4;83281:11;;;:18;83323:4;83309:11;;;:18;83351:4;83337:11;;;:18;83379:4;83365:11;;;:18;83407:4;83393:11;;;:18;83435:4;83421:11;;;:18;83463:4;83449:11;;;:18;83491:4;83477:11;;;:18;83519:4;83505:11;;;:18;83547:4;83533:11;;;:18;83575:4;83561:11;;;:18;83603:4;83589:11;;;:18;83631:4;83617:11;;;:18;83659:4;83645:11;;;:18;83687:4;83673:11;;;:18;83715:4;83701:11;;;:18;83743:4;83729:11;;;:18;83771:4;83757:11;;;:18;83799:4;83785:11;;;:18;83827:4;83813:11;;;:18;82965:7;82874:964::o;81978:589::-;82151:11;;;;82102:16;;;82173:388;80558:2;82193:1;:14;82173:388;;;82259:4;82244:11;;;82243:20;;;82281:12;;;82277:215;;82351:5;82364:1;82351:15;;;;;;;:::i;:::-;;;82334:43;;;;;;909:19:1;;;;944:12;;937:28;;;981:12;;82334:43:0;;;;;;;;;;;;82324:54;;;;;;82313:65;;82277:215;;;82455:8;82465:7;82473:1;82465:10;;;;;;;:::i;:::-;;;;;82438:38;;;;;;;;909:19:1;;;953:2;944:12;;937:28;990:2;981:12;;752:247;82438:38:0;;;;;;;;;;;;;82428:49;;;;;;82417:60;;82277:215;-1:-1:-1;82533:3:0;;82173:388;;;;82124:443;81978:589;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;563:184::-;615:77;612:1;605:88;712:4;709:1;702:15;736:4;733:1;726:15","abiDefinition":[{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"root()":{"notice":"Calculates and returns tree's current root"}},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"MerkleTreeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"count()":"06661abd","historicalRoots(uint256)":"7ea97f40","root()":"ebf0c717","tree()":"fd54b228"}},"solidity/HomeHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b92804997a3979ca0163f8a39c825c97df2a0479a80ee555b1da53d3665d89f464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b92804997a3979ca0163f8a39c825c97df2a0479a80ee555b1da53d3665d89f464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"34204:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;34204:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"34204:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/HomeHarness.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122096df387be66f1aee593fa1d4a2944fcece444aa43bdae2797d8be977840c119e64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122096df387be66f1aee593fa1d4a2944fcece444aa43bdae2797d8be977840c119e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"42574:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;42574:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"42574:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a8ca0e2e4502dcc04ac97920ed2e255a76ea016ce7a168b44075cf841404f8d664736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a8ca0e2e4502dcc04ac97920ed2e255a76ea016ce7a168b44075cf841404f8d664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"91516:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;91516:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"91516:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205e16e39e5bf3bdcd19bdd48b3dc2a33c9284abb928eaea5a5abb24607d9c057464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205e16e39e5bf3bdcd19bdd48b3dc2a33c9284abb928eaea5a5abb24607d9c057464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"88515:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;88515:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"88515:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b6637fa98ecec80322327ba00ad3111d21cd8cd0bb6f3c2a6a53db8478296cb464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b6637fa98ecec80322327ba00ad3111d21cd8cd0bb6f3c2a6a53db8478296cb464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33092:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33092:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33092:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220bbfff1ea24e5e547b993f738b9bbc5e55455507a78805fb3d41437f8386bb22d64736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220bbfff1ea24e5e547b993f738b9bbc5e55455507a78805fb3d41437f8386bb22d64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"844:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;844:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"844:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;3357:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;3357:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/HomeHarness.sol:UpdaterStorage":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"}},"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"NewUpdater(address,address)":{"params":{"newUpdater":"The address of the new updater","oldUpdater":"The address of the old updater"}},"Update(uint32,uint32,bytes32,bytes)":{"params":{"homeDomain":"Domain of home contract","nonce":"Nonce of new merkle root","root":"New merkle root","signature":"Updater's signature on `homeDomain`, `nonce` and `root`"}}},"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"params\":{\"newUpdater\":\"The address of the new updater\",\"oldUpdater\":\"The address of the old updater\"}},\"Update(uint32,uint32,bytes32,bytes)\":{\"params\":{\"homeDomain\":\"Domain of home contract\",\"nonce\":\"Nonce of new merkle root\",\"root\":\"New merkle root\",\"signature\":\"Updater's signature on `homeDomain`, `nonce` and `root`\"}}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"UpdaterStorage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/HomeHarness.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220b9944c73813595f42d27e476ff6f6e703875b299e30d8f60dc86162bbe90001b64736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220b9944c73813595f42d27e476ff6f6e703875b299e30d8f60dc86162bbe90001b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed() public {\n _fail();\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50:33;;82:1;50:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;50:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0xa295154715c075495dc9768e7057b77fdb43b468a2c7383cc0dadec645cd446e\",\"urls\":[\"bzz-raw://1277ee563466798f40ae58a0684c60bf994560c73a4a5e0ff6732dab1538503d\",\"dweb:/ipfs/QmVXfVheySGhcsbXFuALLaB4it1uTrQuuecx8FRCUfX5dU\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file +{"solidity/HomeHarness.sol:AbstractGuardRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"AbstractGuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:AbstractNotaryRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"AbstractNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Address":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122086410a068a5ac131d76eb9679ada0290a3ffe47e5c24d26323ab4ce21f15384d64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122086410a068a5ac131d76eb9679ada0290a3ffe47e5c24d26323ab4ce21f15384d64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"117245:8061:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;117245:8061:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"117245:8061:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Address\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220199284fb3ffd3e57045ba78afcd65635f255f3e4b42774bf260491c1b495c4e064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220199284fb3ffd3e57045ba78afcd65635f255f3e4b42774bf260491c1b495c4e064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"94547:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;94547:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"94547:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122089a7ee9af41c1ca388ec12e23b70ea7aa4690fd8ef84592bf621a254ffabb9e264736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122089a7ee9af41c1ca388ec12e23b70ea7aa4690fd8ef84592bf621a254ffabb9e264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32332:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32332:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32332:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122032e213c688910be4d1ee9b920b12d5255ade3dc923f2229f5d3911503e5b4c6064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122032e213c688910be4d1ee9b920b12d5255ade3dc923f2229f5d3911503e5b4c6064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"46455:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;46455:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"46455:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:DomainNotaryRegistry":{"code":"0x60a060405234801561001057600080fd5b506040516102e73803806102e783398101604081905261002f9161003d565b63ffffffff1660805261006a565b60006020828403121561004f57600080fd5b815163ffffffff8116811461006357600080fd5b9392505050565b608051610265610082600039600050506102656000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207488425b7dac36a7e777e3ea12645cfc70786a290657cd4c09cd3c060cbbbd6864736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207488425b7dac36a7e777e3ea12645cfc70786a290657cd4c09cd3c060cbbbd6864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"59557:5230:0:-:0;;;62646:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62691:30;;;;59557:5230;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;59557:5230:0;;;;;;;;;;;","srcMapRuntime":"59557:5230:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63501:99;;;:::i;:::-;;;160:25:1;;;148:2;133:18;63501:99:0;;;;;;;;63274:105;;;:::i;:::-;;;;;;;:::i;63385:110::-;;;;;;:::i;:::-;;:::i;:::-;;;1243:42:1;1231:55;;;1213:74;;1201:2;1186:18;63385:110:0;1067:226:1;63501:99:0;63550:7;63576:17;:8;:15;:17::i;:::-;63569:24;;63501:99;:::o;63274:105::-;63320:16;63355:17;:8;:15;:17::i;63385:110::-;63443:7;63469:19;63443:7;63481:6;63469:11;:19::i;:::-;63462:26;63385:110;-1:-1:-1;;63385:110:0:o;55788:115::-;55851:7;55877:19;55885:3;51403:18;;51321:107;56941:257;57004:16;57032:22;57057:19;57065:3;57057:7;:19::i;:::-;57032:44;56941:257;-1:-1:-1;;;56941:257:0:o;56245:156::-;56319:7;56369:22;56373:3;56385:5;56369:3;:22::i;52428:109::-;52484:16;52519:3;:11;;52512:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52428:109;;;:::o;51770:118::-;51837:7;51863:3;:11;;51875:5;51863:18;;;;;;;;:::i;:::-;;;;;;;;;51856:25;;51770:118;;;;:::o;196:681:1:-;367:2;419:21;;;489:13;;392:18;;;511:22;;;338:4;;367:2;590:15;;;;564:2;549:18;;;338:4;633:218;647:6;644:1;641:13;633:218;;;712:13;;727:42;708:62;696:75;;826:15;;;;791:12;;;;669:1;662:9;633:218;;;-1:-1:-1;868:3:1;;196:681;-1:-1:-1;;;;;;196:681:1:o;882:180::-;941:6;994:2;982:9;973:7;969:23;965:32;962:52;;;1010:1;1007;1000:12;962:52;-1:-1:-1;1033:23:1;;882:180;-1:-1:-1;882:180:1:o;1298:184::-;1350:77;1347:1;1340:88;1447:4;1444:1;1437:15;1471:4;1468:1;1461:15","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_trackedDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryRemoved","type":"event"},{"inputs":[],"name":"allNotaries","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNotary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notariesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_trackedDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"DomainNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"allNotaries()":"9817e315","getNotary(uint256)":"c07dc7f5","notariesAmount()":"8e62e9ef"}},"solidity/HomeHarness.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220aafb18d6c55b3b9fb8db22621ae0b6eb0d4658287bd164c4c73e5ac0a3b48f0264736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220aafb18d6c55b3b9fb8db22621ae0b6eb0d4658287bd164c4c73e5ac0a3b48f0264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"37529:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;37529:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"37529:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:EnumerableSet":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a3729d0d21bb0e65b1bfc3d61992d75263f9f4ab8d70965923c2ea2ff131867964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a3729d0d21bb0e65b1bfc3d61992d75263f9f4ab8d70965923c2ea2ff131867964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"48187:11368:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;48187:11368:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"48187:11368:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"EnumerableSet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:GuardRegistry":{"code":"0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220f595624ec1951ab2c915d6da09033cc65e8a9add26d338c03bc345f95bdabed964736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220f595624ec1951ab2c915d6da09033cc65e8a9add26d338c03bc345f95bdabed964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"65137:3868:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"65137:3868:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67835:95;;;:::i;:::-;;;160:25:1;;;148:2;133:18;67835:95:0;;;;;;;;67722:107;;;;;;:::i;:::-;;:::i;:::-;;;557:42:1;545:55;;;527:74;;515:2;500:18;67722:107:0;381:226:1;67615:101:0;;;:::i;:::-;;;;;;;:::i;67835:95::-;67882:7;67908:15;:6;:13;:15::i;:::-;67901:22;;67835:95;:::o;67722:107::-;67779:7;67805:17;67779:7;67815:6;67805:9;:17::i;:::-;67798:24;67722:107;-1:-1:-1;;67722:107:0:o;67615:101::-;67659:16;67694:15;:6;:13;:15::i;55788:115::-;55851:7;55877:19;55885:3;51403:18;;51321:107;56245:156;56319:7;56369:22;56373:3;56385:5;56369:3;:22::i;:::-;56361:31;56245:156;-1:-1:-1;;;56245:156:0:o;56941:257::-;57004:16;57032:22;57057:19;57065:3;57057:7;:19::i;51770:118::-;51837:7;51863:3;:11;;51875:5;51863:18;;;;;;;;:::i;:::-;;;;;;;;;51856:25;;51770:118;;;;:::o;52428:109::-;52484:16;52519:3;:11;;52512:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52428:109;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;612:681::-;783:2;835:21;;;905:13;;808:18;;;927:22;;;754:4;;783:2;1006:15;;;;980:2;965:18;;;754:4;1049:218;1063:6;1060:1;1057:13;1049:218;;;1128:13;;1143:42;1124:62;1112:75;;1242:15;;;;1207:12;;;;1085:1;1078:9;1049:218;;;-1:-1:-1;1284:3:1;;612:681;-1:-1:-1;;;;;;612:681:1:o;1298:184::-;1350:77;1347:1;1340:88;1447:4;1444:1;1437:15;1471:4;1468:1;1461:15","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"GuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"allGuards()":"9fe03fa2","getGuard(uint256)":"629ddf69","guardsAmount()":"246c2449"}},"solidity/HomeHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208a54bcee6726d4c5d88de93bea39c64ed524c1b0078615e63008071f9e18931964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208a54bcee6726d4c5d88de93bea39c64ed524c1b0078615e63008071f9e18931964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"78143:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;78143:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"78143:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Home":{"code":"0x60c06040523480156200001157600080fd5b50604051620038c7380380620038c7833981016040819052620000349162000048565b63ffffffff16608081905260a05262000077565b6000602082840312156200005b57600080fd5b815163ffffffff811681146200007057600080fd5b9392505050565b60805160a051613823620000a460003960006118a70152600081816102ef0152610ea501526138236000f3fe6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea26469706673582212204b3dd278e50546afd875e58a557a694ab8bd8303e5d2310e202d5e16d06d649b64736f6c634300080d0033","runtime-code":"0x6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea26469706673582212204b3dd278e50546afd875e58a557a694ab8bd8303e5d2310e202d5e16d06d649b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"125308:12373:0:-:0;;;128362:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113030:26;;;;;;62691:30;;125308:12373;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;125308:12373:0;;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"125308:12373:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116729:81;;;;;;;;;;-1:-1:-1;116793:10:0;;116729:81;;;160:25:1;;;148:2;133:18;116729:81:0;;;;;;;;134209:780;;;;;;;;;;-1:-1:-1;134209:780:0;;;;;:::i;:::-;;:::i;:::-;;;1657:14:1;;1650:22;1632:41;;1620:2;1605:18;134209:780:0;1492:187:1;67835:95:0;;;;;;;;;;;;;:::i;132658:257::-;;;;;;;;;;;;;:::i;:::-;;;;1886:10:1;1874:23;;;1856:42;;1929:2;1914:18;;1907:34;;;;1829:18;132658:257:0;1684:263:1;126214:58:0;;;;;;;;;;;;126263:9;126214:58;;67722:107;;;;;;;;;;-1:-1:-1;67722:107:0;;;;;:::i;:::-;;:::i;:::-;;;2313:42:1;2301:55;;;2283:74;;2271:2;2256:18;67722:107:0;2137:226:1;115346:57:0;;;;;;;;;;;;;:::i;:::-;;116273:32;;;;;;;;;;-1:-1:-1;116273:32:0;;;;;:::i;:::-;;:::i;111819:35::-;;;;;;;;;;;;;;;;;;2724:10:1;2712:23;;;2694:42;;2682:2;2667:18;111819:35:0;2550:192:1;109502:85:0;;;;;;;;;;-1:-1:-1;109574:6:0;;;;109502:85;;63501:99;;;;;;;;;;;;;:::i;130299:140::-;;;;;;;;;;-1:-1:-1;130299:140:0;;;;;:::i;:::-;;:::i;63274:105::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;129627:253::-;;;;;;;;;;-1:-1:-1;129627:253:0;;;;;:::i;:::-;;:::i;126487:37::-;;;;;;;;;;-1:-1:-1;126487:37:0;;;;;;;;;;;67615:101;;;;;;;;;;;;;:::i;126391:19::-;;;;;;;;;;-1:-1:-1;126391:19:0;;;;;;;;115020:133;;;;;;;;;;-1:-1:-1;115020:133:0;;;;;:::i;:::-;;:::i;63385:110::-;;;;;;;;;;-1:-1:-1;63385:110:0;;;;;:::i;:::-;;:::i;126563:19::-;;;;;;;;;;-1:-1:-1;126563:19:0;;;;;;;;;;;;;;;;;;:::i;128573:354::-;;;;;;;;;;-1:-1:-1;128573:354:0;;;;;:::i;:::-;;:::i;112401:39::-;;;;;;;;;;-1:-1:-1;112401:39:0;;;;;;;;116545:81;;;;;;;;;;;;;:::i;110384:198::-;;;;;;;;;;-1:-1:-1;110384:198:0;;;;;:::i;:::-;;:::i;130945:1473::-;;;;;;:::i;:::-;;:::i;116241:26::-;;;;;;;;;;-1:-1:-1;116241:26:0;;;;;;50:33;;;;;;;;;;;;82:1;50:33;;;;;6596:4:1;6584:17;;;6566:36;;6554:2;6539:18;50:33:0;6424:184:1;134209:780:0;134291:4;129345:13;129336:5;;;;;;;:22;;;;;;;;:::i;:::-;;129328:47;;;;-1:-1:-1;;;129328:47:0;;6815:2:1;129328:47:0;;;6797:21:1;6854:2;6834:18;;;6827:30;6893:14;6873:18;;;6866:42;6925:18;;129328:47:0;;;;;;;;;134362:15:::1;134379:13:::0;134396:30:::1;134413:12;134396:16;:30::i;:::-;134361:65;;;;134436:13;134452:24;:5;:22;;;;:24::i;:::-;134436:40:::0;-1:-1:-1;134486:13:0::1;134502:23;-1:-1:-1::0;;134502:21:0;::::1;;:23::i;:::-;134610:15;:22:::0;134486:39;;-1:-1:-1;134601:31:0::1;::::0;::::1;;134597:284;;;134661:15;134677:6;134661:23;;;;;;;;;;:::i;:::-;;;;;;;;;134652:5;:32:::0;134648:139:::1;;-1:-1:-1::0;134767:5:0::1;::::0;134209:780;-1:-1:-1;;;;;134209:780:0:o;134648:139::-:1;134890:14;134896:7;134890:5;:14::i;:::-;134919:42;134939:7;134948:12;134919:42;;;;;;;:::i;:::-;;;;;;;;134978:4;134971:11;;;;;;129385:1;134209:780:::0;;;:::o;67835:95::-;67882:7;67908:15;:6;:13;:15::i;:::-;67901:22;;67835:95;:::o;132658:257::-;132763:15;:22;132706:13;;;;132799:11;;132795:114;;132842:10;132851:1;132842:6;:10;:::i;:::-;132826:27;;132875:15;132891:6;132875:23;;;;;;;;;;:::i;:::-;;;;;;;;;132867:31;;132795:114;132736:179;132658:257;;:::o;67722:107::-;67779:7;67805:17;:6;67815;67805:9;:17::i;:::-;67798:24;67722:107;-1:-1:-1;;67722:107:0:o;115346:57::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;8590:2:1;109706:68:0;;;8572:21:1;;;8609:18;;;8602:30;8668:34;8648:18;;;8641:62;8720:18;;109706:68:0;8388:356:1;109706:68:0;115346:57::o;116273:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116273:32:0;:::o;63501:99::-;63550:7;63576:17;:8;:15;:17::i;130299:140::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;8590:2:1;109706:68:0;;;8572:21:1;;;8609:18;;;8602:30;8668:34;8648:18;;;8641:62;8720:18;;109706:68:0;8388:356:1;109706:68:0;130380:52:::1;130415:15;130380:18;:52::i;:::-;130299:140:::0;:::o;63274:105::-;63320:16;63355:17;:8;:15;:17::i;129627:253::-;129141:14;;;;;;;129119:10;:37;129111:65;;;;-1:-1:-1;;;129111:65:0;;8951:2:1;129111:65:0;;;8933:21:1;8990:2;8970:18;;;8963:30;9029:17;9009:18;;;9002:45;9064:18;;129111:65:0;8749:339:1;129111:65:0;129737:20:::1;129748:8;129737:10;:20::i;:::-;-1:-1:-1::0;;129852:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;129627:253::o;67615:101::-;67659:16;67694:15;:6;:13;:15::i;115020:133::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;8590:2:1;109706:68:0;;;8572:21:1;;;8609:18;;;8602:30;8668:34;8648:18;;;8641:62;8720:18;;109706:68:0;8388:356:1;109706:68:0;115112:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;115020:133::o;63385:110::-;63443:7;63469:19;:8;63481:6;63469:11;:19::i;128573:354::-;104682:19;104704:25;104727:1;104704:22;:25::i;:::-;104682:47;;104743:14;104739:65;;;104773:13;:20;;;;;;;;104739:65;128655:29:::1;:27;:29::i;:::-;128694:35;128713:15;128694:18;:35::i;:::-;128739:36;128750:14;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;128739:10;:36::i;:::-;-1:-1:-1::0;128785:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;128887:15:::1;:33:::0;;-1:-1:-1;128887:33:0;::::1;::::0;;-1:-1:-1;128887:33:0;;;;::::1;::::0;104824:99;;;;104858:13;:21;;;;;;104898:14;;-1:-1:-1;6566:36:1;;104898:14:0;;6554:2:1;6539:18;104898:14:0;;;;;;;104824:99;104672:257;128573:354;:::o;116545:81::-;116582:7;116608:11;:4;:9;:11::i;110384:198::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;8590:2:1;109706:68:0;;;8572:21:1;;;8609:18;;;8602:30;8668:34;8648:18;;;8641:62;8720:18;;109706:68:0;8388:356:1;109706:68:0;110472:22:::1;::::0;::::1;110464:73;;;::::0;-1:-1:-1;;;110464:73:0;;9750:2:1;110464:73:0::1;::::0;::::1;9732:21:1::0;9789:2;9769:18;;;9762:30;9828:34;9808:18;;;9801:62;9899:8;9879:18;;;9872:36;9925:19;;110464:73:0::1;9548:402:1::0;110464:73:0::1;110547:28;110566:8;110547:18;:28::i;130945:1473::-:0;129345:13;129336:5;;;;;;;:22;;;;;;;;:::i;:::-;;129328:47;;;;-1:-1:-1;;;129328:47:0;;6815:2:1;129328:47:0;;;6797:21:1;6854:2;6834:18;;;6827:30;6893:14;6873:18;;;6866:42;6925:18;;129328:47:0;6613:336:1;129328:47:0;126263:9:::1;131182:12;:19;:45;;131174:70;;;::::0;-1:-1:-1;;;131174:70:0;;10157:2:1;131174:70:0::1;::::0;::::1;10139:21:1::0;10196:2;10176:18;;;10169:30;10235:14;10215:18;;;10208:42;10267:18;;131174:70:0::1;9955:336:1::0;131174:70:0::1;131294:9;131262:28;:16;:5;:14;:16::i;:::-;-1:-1:-1::0;;131262:26:0::1;;:28::i;:::-;:41;;;131254:59;;;::::0;-1:-1:-1;;;131254:59:0;;10498:2:1;131254:59:0::1;::::0;::::1;10480:21:1::0;10537:1;10517:18;;;10510:29;10575:7;10555:18;;;10548:35;10600:18;;131254:59:0::1;10296:328:1::0;131254:59:0::1;131407:5;::::0;:9:::1;::::0;:5:::1;;::::0;:9:::1;:::i;:::-;131399:5;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;131444:41:0::1;131467:17:::0;131444:22:::1;:41::i;:::-;131645:5;::::0;79428:242;;;13921:16:1;79428:242:0;;;13905:102:1;14026:66;131599:11:0::1;14129:3:1::0;14125:16;;;14121:25;;14108:11;;;14101:46;14163:11;;;14156:27;;;14217:16;;;;;14199:12;;;14192:47;14273:16;;;14269:25;;14255:12;;;14248:47;14311:12;;;14304:28;;;14366:16;;;;14362:25;;;14348:12;;;14341:47;79428:242:0;;;;;;;;;14404:12:1;;;;79428:242:0;;131426:59;;-1:-1:-1;131813:21:0::1;131837:51;131859:7;131868:5;131875:12;131837:21;:51::i;:::-;131979:19:::0;;::::1;::::0;::::1;::::0;131813:75;;-1:-1:-1;132061:25:0::1;131979:19:::0;132061:11:::1;:25::i;:::-;132354:5;::::0;::::1;;136417:2:::0;136393:26;;;;;136392:37;132240:171:::1;;132298:1;132288:7;116793:10:::0;;;116729:81;132288:7:::1;:11;;;;:::i;:::-;132262:12;132240:171;132374:5;132393:8;132240:171;;;;;;;:::i;:::-;;;;;;;;131164:1254;;;;130945:1473:::0;;;;;:::o;47614:470::-;47714:16;;47769:19;:12;47714:16;47769;:19::i;:::-;47761:27;-1:-1:-1;33025:2:0;2732:26;16554:2;16550:16;;;16546:28;34279:37;47798:52;;;;-1:-1:-1;;;47798:52:0;;11446:2:1;47798:52:0;;;11428:21:1;11485:2;11465:18;;;11458:30;11524:20;11504:18;;;11497:48;11562:18;;47798:52:0;11244:342:1;47798:52:0;47871:115;47903:23;-1:-1:-1;;47903:21:0;;;:23::i;:::-;47940:36;:28;-1:-1:-1;;47940:26:0;;;:28::i;:::-;-1:-1:-1;;47940:34:0;;:36::i;:::-;47871:18;:115::i;:::-;47860:126;-1:-1:-1;48004:46:0;48014:25;-1:-1:-1;;48014:23:0;;;:25::i;:::-;48041:8;48004:9;:46::i;:::-;47996:81;;;;-1:-1:-1;;;47996:81:0;;11793:2:1;47996:81:0;;;11775:21:1;11832:2;11812:18;;;11805:30;11871:24;11851:18;;;11844:52;11913:18;;47996:81:0;11591:346:1;47996:81:0;47614:470;;;:::o;34677:136::-;34741:6;34773:32;-1:-1:-1;;34773:15:0;;32919:1;;34773:15;:32::i;34906:124::-;34969:7;34995:28;-1:-1:-1;;34995:11:0;;32966:1;35020:2;34995:11;:28::i;135611:283::-;135733:5;:21;;;;;;;;;;;;135789:48;;;;;135825:10;135789:14;:48;;2283:74:1;135789:14:0;;;;;;;;;;:27;;2256:18:1;;135789:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;135852:35:0;;135876:10;;-1:-1:-1;135852:35:0;;;;-1:-1:-1;135852:35:0;;;;;135611:283;:::o;55788:115::-;55851:7;55877:19;55885:3;51403:18;;51321:107;56245:156;56319:7;56369:22;56373:3;56385:5;56369:3;:22::i;:::-;56361:31;56245:156;-1:-1:-1;;;56245:156:0:o;135163:285::-;118516:19;;;;135243:81;;;;-1:-1:-1;;;135243:81:0;;12391:2:1;135243:81:0;;;12373:21:1;12430:2;12410:18;;;12403:30;12469:26;12449:18;;;12442:54;12513:18;;135243:81:0;12189:348:1;135243:81:0;135334:14;:49;;;;;;;;;;;;;;;;;;135398:43;;2283:74:1;;;135398:43:0;;2271:2:1;2256:18;135398:43:0;;;;;;;135163:285;:::o;56941:257::-;57004:16;57032:22;57057:19;57065:3;57057:7;:19::i;64146:207::-;64201:16;64243:21;:8;64256:7;64243:12;:21::i;:::-;64229:35;;64278:11;64274:73;;;64310:26;;2313:42:1;2301:55;;2283:74;;64310:26:0;;2271:2:1;2256:18;64310:26:0;;;;;;;64146:207;;;:::o;106858:808::-;107255:13;;106922:4;;107255:13;;;;;107251:409;;;107309:7;:12;;107320:1;107309:12;:61;;;;-1:-1:-1;107364:4:0;118516:19;:23;107309:61;107284:166;;;;-1:-1:-1;;;107284:166:0;;12744:2:1;107284:166:0;;;12726:21:1;12783:2;12763:18;;;12756:30;12822:34;12802:18;;;12795:62;12893:16;12873:18;;;12866:44;12927:19;;107284:166:0;12542:410:1;107284:166:0;-1:-1:-1;107471:5:0;;106858:808;-1:-1:-1;106858:808:0:o;107251:409::-;107515:12;;:22;;;;:12;;:22;107507:81;;;;-1:-1:-1;;;107507:81:0;;12744:2:1;107507:81:0;;;12726:21:1;12783:2;12763:18;;;12756:30;12822:34;12802:18;;;12795:62;12893:16;12873:18;;;12866:44;12927:19;;107507:81:0;12542:410:1;107507:81:0;-1:-1:-1;107602:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;106858:808:0:o;113609:108::-;106269:13;;;;;;;106261:69;;;;-1:-1:-1;;;106261:69:0;;13159:2:1;106261:69:0;;;13141:21:1;13198:2;13178:18;;;13171:30;13237:34;13217:18;;;13210:62;13308:13;13288:18;;;13281:41;13339:19;;106261:69:0;12957:407:1;106261:69:0;113684:26:::1;:24;:26::i;71146:122::-:0;71203:7;71229:32;71241:5;71248:12;:10;:12::i;:::-;71229:11;:32::i;110736:187::-;110828:6;;;;110844:17;;;;;;;;;;;110876:40;;110828:6;;;110844:17;110828:6;;110876:40;;110809:16;;110876:40;110799:124;110736:187;:::o;88128:122::-;88189:7;88215:28;:5;82150:10;88215:9;:28::i;89235:183::-;89308:6;89292:5;87135:35;82150:10;82143:18;-1:-1:-1;;87135:16:0;;;;:35::i;:::-;;89392:19:::1;89405:5;89392:12;:19::i;:::-;89373:16;89383:5;89373:9;:16::i;:::-;89353:17;89364:5;89353:10;:17::i;:::-;89333;89344:5;89333:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;89326:85;;87180:1;89235:183:::0;;;;:::o;136865:814::-;136971:14;90053:24;137005:48;;137001:672;;137105:10;137069:47;134209:780;-1:-1:-1;;134209:780:0:o;137001:672::-;137509:24;:22;:24::i;:::-;-1:-1:-1;90053:24:0;136865:814;;;:::o;83335:638::-;83631:14;;83480:12;;83588:17;;83086:29;83104:10;82957:1;83086:29;:::i;:::-;83608:13;;:38;;;;:::i;:::-;83588:58;;83656:17;83696:5;:12;83676:10;:33;;;;:::i;:::-;83656:53;-1:-1:-1;81807:1:0;83086:29;83104:10;82957:1;83086:29;:::i;:::-;83805:13;;83836:10;83864;83892:7;83917:5;83940:12;83738:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83719:247;;;;83335:638;;;;;:::o;116967:123::-;117022:18;:4;117034:5;117022:11;:18::i;:::-;117050:15;117071:11;:4;:9;:11::i;:::-;117050:33;;;;;;;-1:-1:-1;117050:33:0;;;;;;;;;;;-1:-1:-1;116967:123:0:o;13717:359::-;13821:10;;13787:7;;13968:4;13959:14;;14043:26;;;;13959:14;13821:10;14043:5;:26::i;:::-;14036:33;13717:359;-1:-1:-1;;;;;13717:359:0:o;35136:155::-;35199:7;35225:59;-1:-1:-1;;35225:11:0;;35199:7;33025:2;35199:7;35225:11;:59::i;35374:172::-;35442:7;35468:71;33025:2;35498:37;33025:2;16554;16550:16;;;2732:26;16546:28;35498:37;:::i;:::-;-1:-1:-1;;35468:11:0;;;:71;35537:1;35468:11;:71::i;28370:632::-;28425:16;28453:11;28474:12;28489;28493:7;16554:2;16550:16;2732:26;16546:28;;16308:282;28489:12;28474:27;;;;28611:4;28605:11;28598:18;;28666:3;28659:10;;28712:33;28725:7;28734:3;28740:4;28734:10;28712:12;:33::i;:::-;-1:-1:-1;28869:14:0;;;28885:4;28865:25;28859:4;28852:39;28932:17;;28370:632;;-1:-1:-1;28370:632:0:o;46778:285::-;46888:14;;46935;-1:-1:-1;;46935:12:0;;;:14::i;:::-;46918:31;;46968:36;46997:6;45371:58;;21671:66:1;45371:58:0;;;21659:79:1;21754:12;;;21747:28;;;45241:7:0;;21791:12:1;;45371:58:0;;;;;;;;;;;;45361:69;;;;;;45354:76;;45172:265;;;;46968:36;46959:45;;47023:33;47037:6;47045:10;47023:13;:33::i;:::-;47014:42;46778:285;-1:-1:-1;;;;46778:285:0:o;34420:143::-;34485:6;34517:38;-1:-1:-1;;34517:15:0;;34485:6;34553:1;34517:15;:38::i;64586:199::-;64670:4;64705:13;64694:24;;:7;:24;;;64686:49;;;;-1:-1:-1;;;64686:49:0;;16179:2:1;64686:49:0;;;16161:21:1;16218:2;16198:18;;;16191:30;16257:14;16237:18;;;16230:42;16289:18;;64686:49:0;15977:336:1;64686:49:0;64752:26;:8;64770:7;64752:17;:26::i;21183:221::-;21302:14;21380:11;21385:6;21380:2;:11;:::i;:::-;21379:17;;21395:1;21379:17;:::i;:::-;21335:62;;21343:30;21349:7;21358:6;21366;21343:5;:30::i;:::-;21335:62;;;21183:221;-1:-1:-1;;;;21183:221:0:o;20066:771::-;20181:14;20211:6;:11;;20221:1;20211:11;20207:59;;-1:-1:-1;20253:1:0;20238:17;;20207:59;20297:12;20301:7;16554:2;16550:16;2732:26;16546:28;;16308:282;20297:12;20279:30;;:15;;;;:6;:15;:::i;:::-;:30;20275:137;;;20332:68;20348:12;20352:7;15448:3;15444:17;2732:26;15440:29;;15121:364;20348:12;20332:68;;20362:12;20366:7;16554:2;16550:16;2732:26;16546:28;;16308:282;20362:12;20332:68;;20376:6;20392;20384:15;;20332;:68::i;:::-;20325:76;;-1:-1:-1;;;20325:76:0;;;;;;;;:::i;20275:137::-;20439:2;20429:6;:12;;;;20421:83;;;;-1:-1:-1;;;20421:83:0;;17077:2:1;20421:83:0;;;17059:21:1;17116:2;17096:18;;;17089:30;17155:34;17135:18;;;17128:62;17226:28;17206:18;;;17199:56;17272:19;;20421:83:0;16875:422:1;20421:83:0;20585:1;20576:10;;20515:15;20621:12;20625:7;15448:3;15444:17;2732:26;15440:29;;15121:364;20621:12;20606:27;;;-1:-1:-1;20643:13:0;7550:66;7520:12;;;7499:131;20795:17;;;;20789:24;20785:36;;;-1:-1:-1;;;;;20066:771:0:o;51770:118::-;51837:7;51863:3;:11;;51875:5;51863:18;;;;;;;;:::i;:::-;;;;;;;;;51856:25;;51770:118;;;;:::o;52428:109::-;52484:16;52519:3;:11;;52512:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52428:109;;;:::o;54987:150::-;55057:4;55080:50;55085:3;55105:23;;;55080:4;:50::i;109315:111::-;106269:13;;;;;;;106261:69;;;;-1:-1:-1;;;106261:69:0;;13159:2:1;106261:69:0;;;13141:21:1;13198:2;13178:18;;;13171:30;13237:34;13217:18;;;13210:62;13308:13;13288:18;;;13281:41;13339:19;;106261:69:0;12957:407:1;106261:69:0;109387:32:::1;108502:10:::0;109387:18:::1;:32::i;71386:964::-:0;71431:34;;:::i;:::-;71490:3;71477:16;;71516:3;71477:10;71503;;:16;71542:3;71529:10;;;:16;71568:3;71555:10;;;:16;71594:3;71581:10;;;:16;71620:3;71607:10;;;:16;71646:3;71633:10;;;:16;71672:3;71659:10;;;:16;71698:3;71685:10;;;:16;71724:3;71711:10;;;:16;71751:4;71737:11;;;:18;71779:4;71765:11;;;:18;71807:4;71793:11;;;:18;71835:4;71821:11;;;:18;71863:4;71849:11;;;:18;71891:4;71877:11;;;:18;71919:4;71905:11;;;:18;71947:4;71933:11;;;:18;71975:4;71961:11;;;:18;72003:4;71989:11;;;:18;72031:4;72017:11;;;:18;72059:4;72045:11;;;:18;72087:4;72073:11;;;:18;72115:4;72101:11;;;:18;72143:4;72129:11;;;:18;72171:4;72157:11;;;:18;72199:4;72185:11;;;:18;72227:4;72213:11;;;:18;72255:4;72241:11;;;:18;72283:4;72269:11;;;:18;72311:4;72297:11;;;:18;72339:4;72325:11;;;:18;71477:7;71386:964::o;70490:589::-;70663:11;;;;70614:16;;;70685:388;69070:2;70705:1;:14;70685:388;;;70771:4;70756:11;;;70755:20;;;70793:12;;;70789:215;;70863:5;70876:1;70863:15;;;;;;;:::i;:::-;;;70846:43;;;;;;17459:19:1;;;;17494:12;;17487:28;;;17531:12;;70846:43:0;;;;;;;;;;;;70836:54;;;;;;70825:65;;70789:215;;;70967:8;70977:7;70985:1;70977:10;;;;;;;:::i;:::-;;;;;70950:38;;;;;;;;17459:19:1;;;17503:2;17494:12;;17487:28;17540:2;17531:12;;17302:247;70950:38:0;;;;;;;;;;;;;70940:49;;;;;;70929:60;;70789:215;-1:-1:-1;71045:3:0;;70685:388;;;;70636:443;70490:589;;;;:::o;10135:578::-;10213:7;10237:26;10244:7;10253:9;10237:6;:26::i;:::-;10232:451;;10282:9;10295:35;10313:15;10320:7;14479:3;14475:17;;14268:268;10313:15;10305:24;;10295:9;:35::i;:::-;10279:51;;;10347:9;10360:29;10378:9;10370:18;;10360:9;:29::i;:::-;10447:186;;17921:31:1;10447:186:0;;;17909:44:1;17972:66;18076:3;18072:16;;;18068:25;;18054:12;;;18047:47;18124:15;18110:12;;;18103:37;18174:16;;;18170:25;18156:12;;;18149:47;10344:45:0;;-1:-1:-1;10403:17:0;;-1:-1:-1;18212:12:1;;10447:186:0;;;;;;;;;;;;10403:244;;10668:3;10661:11;;-1:-1:-1;;;10661:11:0;;;;;;;;:::i;10232:451::-;-1:-1:-1;10699:7:0;;10135:578;-1:-1:-1;10135:578:0:o;89076:153::-;89152:6;89136:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;89184:37:0::1;-1:-1:-1::0;;89184:15:0;::::1;87083:2;89218;89184:15;:37::i;:::-;89170:52;;::::0;89076:153;-1:-1:-1;;;89076:153:0:o;88880:147::-;88953:6;88937:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88985:34:0::1;-1:-1:-1::0;;88985:15:0;::::1;87030:2;89016;88985:15;:34::i;88685:149::-:0;88759:6;88743:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88791:35:0::1;-1:-1:-1::0;;88791:15:0;::::1;86980:2;88823;88791:15;:35::i;88489:149::-:0;88563:6;88547:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88595:35:0::1;-1:-1:-1::0;;88595:15:0;::::1;86930:1;88627:2;88595:15;:35::i;115988:132::-:0;116076:15;;;;116054:10;:38;116046:67;;;;-1:-1:-1;;;116046:67:0;;18437:2:1;116046:67:0;;;18419:21:1;18476:2;18456:18;;;18449:30;18515:18;18495;;;18488:46;18551:18;;116046:67:0;18235:340:1;69529:750:0;69614:11;;;;;;69133:1;;69117:13;;:1;:13;:::i;:::-;:17;;;;:::i;:::-;69643:4;:17;69635:46;;;;-1:-1:-1;;;69635:46:0;;20276:2:1;69635:46:0;;;20258:21:1;20315:2;20295:18;;;20288:30;20354:18;20334;;;20327:46;20390:18;;69635:46:0;20074:340:1;69635:46:0;69716:6;;69742:11;;;:18;;;69775:9;69770:319;69070:2;69790:1;:14;69770:319;;;69827:4;69834:1;69827:8;69840:1;69826:15;69822:101;;69879:5;69861;69874:1;69861:15;;;;;;;:::i;:::-;;:23;-1:-1:-1;;;;69529:750:0:o;69822:101::-;69971:5;69984:1;69971:15;;;;;;;:::i;:::-;;;69954:40;;;;;;17459:19:1;;;;17494:12;;17487:28;;;17531:12;;69954:40:0;;;;;;;;;;;;;69944:51;;69954:40;69944:51;;;;;-1:-1:-1;70018:1:0;70009:10;;;;70061:3;69770:319;;;-1:-1:-1;70259:13:0;;:::i;:::-;69589:690;69529:750;;:::o;12858:462::-;12969:15;;13011:11;13018:4;13011;:11;:::i;:::-;12996:26;;13137:4;13131:11;13125:4;13122:21;13119:66;;;-1:-1:-1;13170:1:0;13119:66;13208:4;13216:1;13208:9;13204:51;;-1:-1:-1;;13233:11:0;;;;;13204:51;-1:-1:-1;;12127:2:0;12123:27;;;12197:17;;;;12189:26;;;12261:17;12257:2;12253:26;;12858:462::o;17191:399::-;17330:7;17349:12;17364;17368:7;15448:3;15444:17;2732:26;15440:29;;15121:364;17364:12;17349:27;;;;17460:12;17464:7;17460:3;:12::i;:::-;17453:4;17437:13;17444:6;17437:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17433:77;;;-1:-1:-1;;17488:11:0;;;;;17433:77;17527:13;17534:6;17527:4;:13;:::i;:::-;17520:20;;17557:26;17563:7;17557:26;;17572:4;17578;17557:5;:26::i;:::-;17550:33;17191:399;-1:-1:-1;;;;;;17191:399:0:o;27098:902::-;27176:15;-1:-1:-1;;8034:15:0;;;;27203:69;;;;-1:-1:-1;;;27203:69:0;;20810:2:1;27203:69:0;;;20792:21:1;20849:2;20829:18;;;20822:30;20888:34;20868:18;;;20861:62;20959:10;20939:18;;;20932:38;20987:19;;27203:69:0;20608:404:1;27203:69:0;27290:16;27298:7;27290;:16::i;:::-;27282:72;;;;-1:-1:-1;;;27282:72:0;;21219:2:1;27282:72:0;;;21201:21:1;21258:2;21238:18;;;21231:30;21297:34;21277:18;;;21270:62;21368:13;21348:18;;;21341:41;21399:19;;27282:72:0;21017:407:1;27282:72:0;27364:12;27379;27383:7;16554:2;16550:16;2732:26;16546:28;;16308:282;27379:12;27364:27;;;;27401:15;27419:12;27423:7;15448:3;15444:17;2732:26;15440:29;;15121:364;27419:12;27401:30;;;;27442:11;27563:4;27557:11;27550:18;;27650:7;27645:3;27642:16;27639:94;;;27690:4;27684;27677:18;27639:94;27905:4;27896:7;27890:4;27881:7;27878:1;27871:5;27860:50;27856:55;27941:52;27962:15;27969:7;14479:3;14475:17;;14268:268;27962:15;12123:27;12127:2;12123:27;;;;12197:17;;12189:26;;12261:17;;12257:2;12253:26;;11873:446;22517:290;22573:14;22599:12;22614;22618:7;15448:3;15444:17;2732:26;15440:29;;15121:364;22614:12;22599:27;;;;22636:12;22651;22655:7;16554:2;16550:16;2732:26;16546:28;;16308:282;22651:12;22636:27;;22770:21;;;;22517:290;-1:-1:-1;;;22517:290:0:o;41468:227::-;41546:7;41566:17;41585:18;41607:27;41618:4;41624:9;41607:10;:27::i;:::-;41565:69;;;;41644:18;41656:5;41644:11;:18::i;:::-;-1:-1:-1;41679:9:0;41468:227;-1:-1:-1;;;41468:227:0:o;55542:165::-;55675:23;;;55622:4;51209:19;;;:12;;;:19;;;;;;:24;;55645:55;51113:127;18823:741;18969:17;19001:9;19014:15;19024:4;19014:9;:15::i;:::-;18998:31;;;19042:9;19055:15;19065:4;19055:9;:15::i;:::-;19039:31;;;19083:9;19096:17;19106:6;19096:9;:17::i;:::-;19080:33;;;19126:9;19139:17;19149:6;19139:9;:17::i;:::-;19123:33;;;19306:1;19368;19448;19510;19192:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19166:391;;18988:576;;;;18823:741;;;;;;:::o;49072:404::-;49135:4;51209:19;;;:12;;;:19;;;;;;49151:319;;-1:-1:-1;49193:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;49373:18;;49351:19;;;:12;;;:19;;;;;;:40;;;;49405:11;;49151:319;-1:-1:-1;49454:5:0;49447:12;;9705:132;9779:4;9821:9;9802:28;;:15;9809:7;14479:3;14475:17;;14268:268;9802:15;:28;;;;9705:132;-1:-1:-1;;;9705:132:0:o;5093:667::-;5147:13;;5203:2;5188:258;5211:2;5207:1;:6;;;5188:258;;;5231:11;5258:5;:1;5262;5258:5;:::i;:::-;5251:13;;:2;:13;;5231:34;;5288:14;5296:5;5288:7;:14::i;:::-;5279:23;;;;;;5320:1;:7;;5325:2;5320:7;5316:58;;5357:2;5347:12;;;;;5316:58;-1:-1:-1;5415:6:0;;5188:258;;;-1:-1:-1;5509:2:0;5494:260;5517:3;5513:1;:7;;;5494:260;;;5538:11;5565:5;:1;5569;5565:5;:::i;:::-;5558:13;;:2;:13;;5538:34;;5596:14;5604:5;5596:7;:14::i;:::-;5586:24;;;;;;5628:1;:6;;5633:1;5628:6;5624:58;;5665:2;5654:13;;;;;5624:58;-1:-1:-1;5723:6:0;;5494:260;;;;5093:667;;;:::o;16764:147::-;16817:7;16882:12;16886:7;16554:2;16550:16;2732:26;16546:28;;16308:282;16882:12;16867;16871:7;15448:3;15444:17;2732:26;15440:29;;15121:364;16867:12;:27;16860:34;;;;16764:147;;;:::o;8707:333::-;8764:8;8788:15;8795:7;14479:3;14475:17;;14268:268;8788:15;:31;;8807:12;8788:31;8784:74;;-1:-1:-1;8842:5:0;;8707:333;-1:-1:-1;8707:333:0:o;8784:74::-;8867:12;8882;8886:7;8882:3;:12::i;:::-;9017:4;9011:11;-1:-1:-1;8998:26:0;;8707:333;-1:-1:-1;;;8707:333:0:o;39403:1279::-;39484:7;39493:12;39714:9;:16;39734:2;39714:22;39710:966;;40003:4;39988:20;;39982:27;40052:4;40037:20;;40031:27;40109:4;40094:20;;40088:27;39752:9;40080:36;40150:25;40161:4;40080:36;39982:27;40031;40150:10;:25::i;:::-;40143:32;;;;;;;;;39710:966;40196:9;:16;40216:2;40196:22;40192:484;;40465:4;40450:20;;40444:27;40515:4;40500:20;;40494:27;40555:23;40566:4;40444:27;40494;40555:10;:23::i;:::-;40548:30;;;;;;;;40192:484;-1:-1:-1;40625:1:0;;-1:-1:-1;40629:35:0;40192:484;39403:1279;;;;;:::o;37708:631::-;37785:20;37776:5;:29;;;;;;;;:::i;:::-;;37772:561;;37708:631;:::o;37772:561::-;37881:29;37872:5;:38;;;;;;;;:::i;:::-;;37868:465;;37926:34;;-1:-1:-1;;;37926:34:0;;23531:2:1;37926:34:0;;;23513:21:1;23570:2;23550:18;;;23543:30;23609:26;23589:18;;;23582:54;23653:18;;37926:34:0;23329:348:1;37868:465:0;37990:35;37981:5;:44;;;;;;;;:::i;:::-;;37977:356;;38041:41;;-1:-1:-1;;;38041:41:0;;23884:2:1;38041:41:0;;;23866:21:1;23923:2;23903:18;;;23896:30;23962:33;23942:18;;;23935:61;24013:18;;38041:41:0;23682:355:1;37977:356:0;38112:30;38103:5;:39;;;;;;;;:::i;:::-;;38099:234;;38158:44;;-1:-1:-1;;;38158:44:0;;24244:2:1;38158:44:0;;;24226:21:1;24283:2;24263:18;;;24256:30;24322:34;24302:18;;;24295:62;24393:4;24373:18;;;24366:32;24415:19;;38158:44:0;24042:398:1;38099:234:0;38232:30;38223:5;:39;;;;;;;;:::i;:::-;;38219:114;;38278:44;;-1:-1:-1;;;38278:44:0;;24647:2:1;38278:44:0;;;24629:21:1;24686:2;24666:18;;;24659:30;24725:34;24705:18;;;24698:62;24796:4;24776:18;;;24769:32;24818:19;;38278:44:0;24445:398:1;4570:199:0;4620:14;4657:18;4673:1;4667:2;:7;;;;4657:9;:18::i;:::-;4646:29;;4699:13;;;;;;4711:1;4699:13;4733;4743:2;4733:9;:13::i;:::-;4722:24;;;;4570:199;-1:-1:-1;4570:199:0:o;42876:1603::-;43002:7;;43926:66;43913:79;;43909:161;;;-1:-1:-1;44024:1:0;;-1:-1:-1;44028:30:0;44008:51;;43909:161;44083:1;:7;;44088:2;44083:7;;:18;;;;;44094:1;:7;;44099:2;44094:7;;44083:18;44079:100;;;-1:-1:-1;44133:1:0;;-1:-1:-1;44137:30:0;44117:51;;44079:100;44290:24;;;44273:14;44290:24;;;;;;;;;25075:25:1;;;25148:4;25136:17;;25116:18;;;25109:45;;;;25170:18;;;25163:34;;;25213:18;;;25206:34;;;44290:24:0;;25047:19:1;;44290:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44290:24:0;;;;;;-1:-1:-1;;44328:20:0;;;44324:101;;44380:1;44384:29;44364:50;;;;;;;44324:101;44443:6;-1:-1:-1;44451:20:0;;-1:-1:-1;42876:1603:0;;;;;;;;:::o;41949:336::-;42059:7;;42117:66;42104:80;;42059:7;42210:25;42226:3;42211:18;;;42233:2;42210:25;:::i;:::-;42194:42;;42253:25;42264:4;42270:1;42273;42276;42253:10;:25::i;:::-;42246:32;;;;;;41949:336;;;;;;:::o;3005:1393::-;3057:10;3223:4;3218:9;;;;3269:15;;;;;3265:57;;-1:-1:-1;3307:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3265:57::-;3340:7;:15;;3351:4;3340:15;3336:57;;-1:-1:-1;3378:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3336:57::-;3411:7;:15;;3422:4;3411:15;3407:57;;-1:-1:-1;3449:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3407:57::-;3482:7;:15;;3493:4;3482:15;3478:57;;-1:-1:-1;3520:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3478:57::-;3553:7;:15;;3564:4;3553:15;3549:57;;-1:-1:-1;3591:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3549:57::-;3624:7;:15;;3635:4;3624:15;3620:57;;-1:-1:-1;3662:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3620:57::-;3695:7;:15;;3706:4;3695:15;3691:57;;-1:-1:-1;3733:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3691:57::-;3766:7;:15;;3777:4;3766:15;3762:57;;-1:-1:-1;3804:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3762:57::-;3837:7;:15;;3848:4;3837:15;3833:57;;-1:-1:-1;3875:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3833:57::-;3908:7;:15;;3919:4;3908:15;3904:57;;-1:-1:-1;3946:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3904:57::-;3979:7;:15;;3990:4;3979:15;3975:57;;-1:-1:-1;4017:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3975:57::-;4050:7;:15;;4061:4;4050:15;4046:57;;-1:-1:-1;4088:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4046:57::-;4121:7;:15;;4132:4;4121:15;4117:57;;-1:-1:-1;4159:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4117:57::-;4192:7;:15;;4203:4;4192:15;4188:57;;-1:-1:-1;4230:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4188:57::-;4263:7;:15;;4274:4;4263:15;4259:57;;-1:-1:-1;4301:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4259:57::-;4334:7;:15;;4345:4;4334:15;4330:57;;-1:-1:-1;4372:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:184:1:-;248:77;245:1;238:88;345:4;342:1;335:15;369:4;366:1;359:15;385:777;427:5;480:3;473:4;465:6;461:17;457:27;447:55;;498:1;495;488:12;447:55;534:6;521:20;560:18;597:2;593;590:10;587:36;;;603:18;;:::i;:::-;737:2;731:9;799:4;791:13;;642:66;787:22;;;811:2;783:31;779:40;767:53;;;835:18;;;855:22;;;832:46;829:72;;;881:18;;:::i;:::-;921:10;917:2;910:22;956:2;948:6;941:18;1002:3;995:4;990:2;982:6;978:15;974:26;971:35;968:55;;;1019:1;1016;1009:12;968:55;1083:2;1076:4;1068:6;1064:17;1057:4;1049:6;1045:17;1032:54;1130:1;1123:4;1118:2;1110:6;1106:15;1102:26;1095:37;1150:6;1141:15;;;;;;385:777;;;;:::o;1167:320::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;1344:9;1331:23;1377:18;1369:6;1366:30;1363:50;;;1409:1;1406;1399:12;1363:50;1432:49;1473:7;1464:6;1453:9;1449:22;1432:49;:::i;1952:180::-;2011:6;2064:2;2052:9;2043:7;2039:23;2035:32;2032:52;;;2080:1;2077;2070:12;2032:52;-1:-1:-1;2103:23:1;;1952:180;-1:-1:-1;1952:180:1:o;2747:154::-;2833:42;2826:5;2822:54;2815:5;2812:65;2802:93;;2891:1;2888;2881:12;2906:247;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3073:9;3060:23;3092:31;3117:5;3092:31;:::i;3158:681::-;3329:2;3381:21;;;3451:13;;3354:18;;;3473:22;;;3300:4;;3329:2;3552:15;;;;3526:2;3511:18;;;3300:4;3595:218;3609:6;3606:1;3603:13;3595:218;;;3674:13;;3689:42;3670:62;3658:75;;3788:15;;;;3753:12;;;;3631:1;3624:9;3595:218;;;-1:-1:-1;3830:3:1;;3158:681;-1:-1:-1;;;;;;3158:681:1:o;4376:184::-;4428:77;4425:1;4418:88;4525:4;4522:1;4515:15;4549:4;4546:1;4539:15;4565:396;4708:2;4693:18;;4741:1;4730:13;;4720:201;;4777:77;4774:1;4767:88;4878:4;4875:1;4868:15;4906:4;4903:1;4896:15;4720:201;4930:25;;;4565:396;:::o;5498:163::-;5565:20;;5625:10;5614:22;;5604:33;;5594:61;;5651:1;5648;5641:12;5666:753;5777:6;5785;5793;5801;5809;5862:3;5850:9;5841:7;5837:23;5833:33;5830:53;;;5879:1;5876;5869:12;5830:53;5902:28;5920:9;5902:28;:::i;:::-;5892:38;;5977:2;5966:9;5962:18;5949:32;5939:42;;6000:37;6033:2;6022:9;6018:18;6000:37;:::i;:::-;5990:47;;6088:2;6077:9;6073:18;6060:32;6111:18;6152:2;6144:6;6141:14;6138:34;;;6168:1;6165;6158:12;6138:34;6191:49;6232:7;6223:6;6212:9;6208:22;6191:49;:::i;:::-;6181:59;;6293:3;6282:9;6278:19;6265:33;6249:49;;6323:2;6313:8;6310:16;6307:36;;;6339:1;6336;6329:12;6307:36;;6362:51;6405:7;6394:8;6383:9;6379:24;6362:51;:::i;:::-;6352:61;;;5666:753;;;;;;;;:::o;6954:184::-;7006:77;7003:1;6996:88;7103:4;7100:1;7093:15;7127:4;7124:1;7117:15;7143:258;7215:1;7225:113;7239:6;7236:1;7233:13;7225:113;;;7315:11;;;7309:18;7296:11;;;7289:39;7261:2;7254:10;7225:113;;;7356:6;7353:1;7350:13;7347:48;;;7391:1;7382:6;7377:3;7373:16;7366:27;7347:48;;7143:258;;;:::o;7406:316::-;7447:3;7485:5;7479:12;7512:6;7507:3;7500:19;7528:63;7584:6;7577:4;7572:3;7568:14;7561:4;7554:5;7550:16;7528:63;:::i;:::-;7636:2;7624:15;7641:66;7620:88;7611:98;;;;7711:4;7607:109;;7406:316;-1:-1:-1;;7406:316:1:o;7727:337::-;7914:42;7906:6;7902:55;7891:9;7884:74;7994:2;7989;7978:9;7974:18;7967:30;7865:4;8014:44;8054:2;8043:9;8039:18;8031:6;8014:44;:::i;8069:184::-;8121:77;8118:1;8111:88;8218:4;8215:1;8208:15;8242:4;8239:1;8232:15;8258:125;8298:4;8326:1;8323;8320:8;8317:34;;;8331:18;;:::i;:::-;-1:-1:-1;8368:9:1;;8258:125::o;9093:251::-;9163:6;9216:2;9204:9;9195:7;9191:23;9187:32;9184:52;;;9232:1;9229;9222:12;9184:52;9264:9;9258:16;9283:31;9308:5;9283:31;:::i;10629:228::-;10668:3;10696:10;10733:2;10730:1;10726:10;10763:2;10760:1;10756:10;10794:3;10790:2;10786:12;10781:3;10778:21;10775:47;;;10802:18;;:::i;:::-;10838:13;;10629:228;-1:-1:-1;;;;10629:228:1:o;10862:377::-;11055:2;11044:9;11037:21;11018:4;11081:44;11121:2;11110:9;11106:18;11098:6;11081:44;:::i;:::-;11173:9;11165:6;11161:22;11156:2;11145:9;11141:18;11134:50;11201:32;11226:6;11218;11201:32;:::i;13369:244::-;13408:3;13436:26;13489:2;13486:1;13482:10;13519:2;13516:1;13512:10;13550:3;13546:2;13542:12;13537:3;13534:21;13531:47;;;13558:18;;:::i;14427:238::-;14465:7;14505:4;14502:1;14498:12;14537:4;14534:1;14530:12;14597:3;14591:4;14587:14;14582:3;14579:23;14572:3;14565:11;14558:19;14554:49;14551:75;;;14606:18;;:::i;:::-;14646:13;;14427:238;-1:-1:-1;;;14427:238:1:o;14670:224::-;14709:3;14737:6;14770:2;14767:1;14763:10;14800:2;14797:1;14793:10;14831:3;14827:2;14823:12;14818:3;14815:21;14812:47;;;14839:18;;:::i;14899:1073::-;15224:3;15252:66;15361:2;15352:6;15347:3;15343:16;15339:25;15334:3;15327:38;15416:2;15407:6;15402:3;15398:16;15394:25;15390:1;15385:3;15381:11;15374:46;15471:2;15462:6;15457:3;15453:16;15449:25;15445:1;15440:3;15436:11;15429:46;15526:2;15517:6;15512:3;15508:16;15504:25;15500:1;15495:3;15491:11;15484:46;;15559:6;15553:13;15575:61;15629:6;15625:1;15620:3;15616:11;15609:4;15601:6;15597:17;15575:61;:::i;:::-;15696:13;;15655:16;;;;15718:62;15696:13;15767:1;15759:10;;15752:4;15740:17;;15718:62;:::i;:::-;15841:13;;15799:17;;;15863:62;15841:13;15912:1;15904:10;;15897:4;15885:17;;15863:62;:::i;:::-;15945:17;15964:1;15941:25;;14899:1073;-1:-1:-1;;;;;;;;;14899:1073:1:o;16318:195::-;16356:4;16393;16390:1;16386:12;16425:4;16422:1;16418:12;16450:3;16445;16442:12;16439:38;;;16457:18;;:::i;:::-;16494:13;;;16318:195;-1:-1:-1;;;16318:195:1:o;16518:128::-;16558:3;16589:1;16585:6;16582:1;16579:13;16576:39;;;16595:18;;:::i;:::-;-1:-1:-1;16631:9:1;;16518:128::o;16651:219::-;16800:2;16789:9;16782:21;16763:4;16820:44;16860:2;16849:9;16845:18;16837:6;16820:44;:::i;18580:482::-;18669:1;18712:5;18669:1;18726:330;18747:7;18737:8;18734:21;18726:330;;;18866:4;18798:66;18794:77;18788:4;18785:87;18782:113;;;18875:18;;:::i;:::-;18925:7;18915:8;18911:22;18908:55;;;18945:16;;;;18908:55;19024:22;;;;18984:15;;;;18726:330;;;18730:3;18580:482;;;;;:::o;19067:866::-;19116:5;19146:8;19136:80;;-1:-1:-1;19187:1:1;19201:5;;19136:80;19235:4;19225:76;;-1:-1:-1;19272:1:1;19286:5;;19225:76;19317:4;19335:1;19330:59;;;;19403:1;19398:130;;;;19310:218;;19330:59;19360:1;19351:10;;19374:5;;;19398:130;19435:3;19425:8;19422:17;19419:43;;;19442:18;;:::i;:::-;-1:-1:-1;;19498:1:1;19484:16;;19513:5;;19310:218;;19612:2;19602:8;19599:16;19593:3;19587:4;19584:13;19580:36;19574:2;19564:8;19561:16;19556:2;19550:4;19547:12;19543:35;19540:77;19537:159;;;-1:-1:-1;19649:19:1;;;19681:5;;19537:159;19728:34;19753:8;19747:4;19728:34;:::i;:::-;19858:6;19790:66;19786:79;19777:7;19774:92;19771:118;;;19869:18;;:::i;19938:131::-;19998:5;20027:36;20054:8;20048:4;20027:36;:::i;20419:184::-;20471:77;20468:1;20461:88;20568:4;20565:1;20558:15;20592:4;20589:1;20582:15;21933:1391;22655:34;22643:47;;22720:23;22715:2;22706:12;;22699:45;22763:66;22867:3;22863:16;;;22859:25;;22854:2;22845:12;;22838:47;22904:17;22946:2;22937:12;;22930:24;;;22988:16;;;22984:25;;22979:2;22970:12;;22963:47;23040:34;23035:2;23026:12;;23019:56;23106:3;23100;23091:13;;23084:26;23145:16;;;23141:25;;23135:3;23126:13;;23119:48;23192:3;23183:13;;23176:25;23236:16;;;23232:25;23226:3;23217:13;;23210:48;21891:3;23313;23304:13;;21879:16;-1:-1:-1;21911:11:1;;;23274:44;21814:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"leafIndex","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"destinationAndNonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"tips","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Dispatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"ImproperAttestation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updaterManager","type":"address"}],"name":"NewUpdaterManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"address","name":"reporter","type":"address"}],"name":"UpdaterSlashed","type":"event"},{"inputs":[],"name":"MAX_MESSAGE_BODY_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allNotaries","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipientAddress","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNotary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"improperAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUpdaterManager","name":"_updaterManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notariesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterManager","type":"address"}],"name":"setUpdaterManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Home.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"suggestUpdate","outputs":[{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updaterManager","outputs":[{"internalType":"contract IUpdaterManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"notice":"Emitted when a new message is dispatched via Nomad"},"ImproperAttestation(address,bytes)":{"notice":"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state"},"NewUpdaterManager(address)":{"notice":"Emitted when the UpdaterManager contract is changed"},"UpdaterSlashed(address,address)":{"notice":"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)"}},"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"notice":"Dispatch the message to the destination domain \u0026 recipient"},"improperAttestation(bytes)":{"notice":"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation."},"root()":{"notice":"Calculates and returns tree's current root"},"setUpdater(address)":{"notice":"Set a new Updater"},"setUpdaterManager(address)":{"notice":"Set a new UpdaterManager contract"},"suggestUpdate()":{"notice":"Suggest an update for the Updater to sign and submit."}},"version":1},"developerDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"params":{"destinationAndNonce":"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)","leafIndex":"Index of message's leaf in merkle tree","message":"Raw bytes of message","messageHash":"Hash of message; the leaf inserted to the Merkle tree for the message","tips":"Tips paid for the remote off-chain agents"}},"ImproperAttestation(address,bytes)":{"params":{"attestation":"Attestation data and signature","updater":"Updater who signed improper attestation"}},"NewUpdaterManager(address)":{"params":{"updaterManager":"The address of the new updaterManager"}},"UpdaterSlashed(address,address)":{"params":{"reporter":"The address of the entity that reported the updater misbehavior","updater":"The address of the updater"}}},"kind":"dev","methods":{"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"details":"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.","params":{"_destinationDomain":"Domain of destination chain","_messageBody":"Raw bytes content of message","_recipientAddress":"Address of recipient on destination chain as bytes32"}},"improperAttestation(bytes)":{"details":"Reverts (and doesn't slash updater) if signature is invalid or update not current","params":{"_attestation":"Attestation data and signature"},"returns":{"_0":"TRUE if update was an Improper Attestation (implying Updater was slashed)"}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setUpdater(address)":{"details":"To be set when rotating Updater after Fraud","params":{"_updater":"the new Updater"}},"setUpdaterManager(address)":{"details":"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation","params":{"_updaterManager":"the new UpdaterManager contract"}},"suggestUpdate()":{"details":"If no messages have been sent, null bytes returned for both","returns":{"_nonce":"Current nonce","_root":"Current merkle root"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum Home.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"params\":{\"destinationAndNonce\":\"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\",\"leafIndex\":\"Index of message's leaf in merkle tree\",\"message\":\"Raw bytes of message\",\"messageHash\":\"Hash of message; the leaf inserted to the Merkle tree for the message\",\"tips\":\"Tips paid for the remote off-chain agents\"}},\"ImproperAttestation(address,bytes)\":{\"params\":{\"attestation\":\"Attestation data and signature\",\"updater\":\"Updater who signed improper attestation\"}},\"NewUpdaterManager(address)\":{\"params\":{\"updaterManager\":\"The address of the new updaterManager\"}},\"UpdaterSlashed(address,address)\":{\"params\":{\"reporter\":\"The address of the entity that reported the updater misbehavior\",\"updater\":\"The address of the updater\"}}},\"kind\":\"dev\",\"methods\":{\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"details\":\"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.\",\"params\":{\"_destinationDomain\":\"Domain of destination chain\",\"_messageBody\":\"Raw bytes content of message\",\"_recipientAddress\":\"Address of recipient on destination chain as bytes32\"}},\"improperAttestation(bytes)\":{\"details\":\"Reverts (and doesn't slash updater) if signature is invalid or update not current\",\"params\":{\"_attestation\":\"Attestation data and signature\"},\"returns\":{\"_0\":\"TRUE if update was an Improper Attestation (implying Updater was slashed)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setUpdater(address)\":{\"details\":\"To be set when rotating Updater after Fraud\",\"params\":{\"_updater\":\"the new Updater\"}},\"setUpdaterManager(address)\":{\"details\":\"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\",\"params\":{\"_updaterManager\":\"the new UpdaterManager contract\"}},\"suggestUpdate()\":{\"details\":\"If no messages have been sent, null bytes returned for both\",\"returns\":{\"_nonce\":\"Current nonce\",\"_root\":\"Current merkle root\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"notice\":\"Emitted when a new message is dispatched via Nomad\"},\"ImproperAttestation(address,bytes)\":{\"notice\":\"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state\"},\"NewUpdaterManager(address)\":{\"notice\":\"Emitted when the UpdaterManager contract is changed\"},\"UpdaterSlashed(address,address)\":{\"notice\":\"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)\"}},\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Dispatch the message to the destination domain \u0026 recipient\"},\"improperAttestation(bytes)\":{\"notice\":\"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation.\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"},\"setUpdater(address)\":{\"notice\":\"Set a new Updater\"},\"setUpdaterManager(address)\":{\"notice\":\"Set a new UpdaterManager contract\"},\"suggestUpdate()\":{\"notice\":\"Suggest an update for the Updater to sign and submit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Home\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"MAX_MESSAGE_BODY_BYTES()":"522ae002","VERSION()":"ffa1ad74","allGuards()":"9fe03fa2","allNotaries()":"9817e315","count()":"06661abd","dispatch(uint32,bytes32,uint32,bytes,bytes)":"f7560e40","getGuard(uint256)":"629ddf69","getNotary(uint256)":"c07dc7f5","guardsAmount()":"246c2449","historicalRoots(uint256)":"7ea97f40","improperAttestation(bytes)":"0afe7f90","initialize(address)":"c4d66de8","localDomain()":"8d3638f4","nonce()":"affed0e0","notariesAmount()":"8e62e9ef","owner()":"8da5cb5b","renounceOwnership()":"715018a6","root()":"ebf0c717","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","setUpdaterManager(address)":"9776120e","state()":"c19d93fb","suggestUpdate()":"36e104de","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","tree()":"fd54b228","updaterManager()":"9df6c8e1"}},"solidity/HomeHarness.sol:HomeHarness":{"code":"0x60c06040523480156200001157600080fd5b5060405162003a4138038062003a41833981016040819052620000349162000048565b63ffffffff16608081905260a05262000077565b6000602082840312156200005b57600080fd5b815163ffffffff811681146200007057600080fd5b9392505050565b60805160a051613996620000ab600039600061171101526000818161035d01528181610ce30152610ff001526139966000f3fe6080604052600436106101e35760003560e01c80639df6c8e111610102578063ccbdf9c911610095578063f2fde38b11610064578063f2fde38b146105fe578063f7560e401461061e578063fd54b22814610631578063ffa1ad741461064857600080fd5b8063ccbdf9c914610563578063da180e7014610590578063ebf0c717146105c9578063f13eed97146105de57600080fd5b8063b7bc563e116100d1578063b7bc563e146104bf578063c07dc7f5146104df578063c19d93fb146104ff578063c4d66de81461054357600080fd5b80639df6c8e1146104365780639fe03fa21461046c578063a1191a5114610481578063affed0e0146104a157600080fd5b8063715018a61161017a5780638e62e9ef116101495780638e62e9ef146103bf5780639776120e146103d45780639817e315146103f45780639d54f4191461041657600080fd5b8063715018a6146103165780637ea97f401461032b5780638d3638f41461034b5780638da5cb5b1461039457600080fd5b806336e104de116101b657806336e104de1461026857806348639d2414610299578063522ae002146102bb578063629ddf69146102d157600080fd5b806306661abd146101e8578063089d28941461020c5780630afe7f9014610223578063246c244914610253575b600080fd5b3480156101f457600080fd5b506020545b6040519081526020015b60405180910390f35b34801561021857600080fd5b506101f961014e5481565b34801561022f57600080fd5b5061024361023e3660046131c2565b61066f565b6040519015158152602001610203565b34801561025f57600080fd5b506101f96107c6565b34801561027457600080fd5b5061027d6107d7565b6040805163ffffffff9093168352602083019190915201610203565b3480156102a557600080fd5b506102b96102b43660046131f7565b61081e565b005b3480156102c757600080fd5b506101f961080081565b3480156102dd57600080fd5b506102f16102ec3660046131f7565b61082c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610203565b34801561032257600080fd5b506102b961083f565b34801561033757600080fd5b506101f96103463660046131f7565b6108a8565b34801561035757600080fd5b5061037f7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610203565b3480156103a057600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff166102f1565b3480156103cb57600080fd5b506101f96108c9565b3480156103e057600080fd5b506102b96103ef366004613232565b6108d5565b34801561040057600080fd5b50610409610948565b604051610203919061324f565b34801561042257600080fd5b506102b9610431366004613232565b610954565b34801561044257600080fd5b5061011e546102f190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561047857600080fd5b50610409610a15565b34801561048d57600080fd5b506102b961049c366004613232565b610a21565b3480156104ad57600080fd5b5061011e5461037f9063ffffffff1681565b3480156104cb57600080fd5b506102b96104da366004613232565b610a2a565b3480156104eb57600080fd5b506102f16104fa3660046131f7565b610ad8565b34801561050b57600080fd5b5061011e54610536907801000000000000000000000000000000000000000000000000900460ff1681565b60405161020391906132d8565b34801561054f57600080fd5b506102b961055e366004613232565b610ae5565b34801561056f57600080fd5b5060b7546102f19073ffffffffffffffffffffffffffffffffffffffff1681565b34801561059c57600080fd5b506105b06105ab36600461332d565b610caf565b60405167ffffffffffffffff9091168152602001610203565b3480156105d557600080fd5b506101f9610cd0565b3480156105ea57600080fd5b506102436105f9366004613232565b610cdc565b34801561060a57600080fd5b506102b9610619366004613232565b610d08565b6102b961062c366004613360565b610e01565b34801561063d57600080fd5b506020546101f99081565b34801561065457600080fd5b5061065d600081565b60405160ff9091168152602001610203565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156106a7576106a76132a9565b036106f95760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080610705846110fb565b91509150600061071a8262ffffff191661120b565b9050600061072d62ffffff19841661121f565b60215490915063ffffffff831610156107765760218263ffffffff1681548110610759576107596133ef565b906000526020600020015481036107765750600095945050505050565b61077f84611234565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516107b0929190613498565b60405180910390a160019450505050505b919050565b60006107d260eb61134c565b905090565b60215460009081908015610819576107f06001826134f6565b925060218363ffffffff168154811061080b5761080b6133ef565b906000526020600020015491505b509091565b610826611356565b61014e55565b600061083960eb836113bd565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b565b602181815481106108b857600080fd5b600091825260209091200154905081565b60006107d260b861134c565b60855473ffffffffffffffffffffffffffffffffffffffff16331461093c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b610945816113c9565b50565b60606107d260b86114b1565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146109c45760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e61676572000000000000000000000000000000000060448201526064016106f0565b6109cd816114be565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606107d260eb6114b1565b61094581611234565b60855473ffffffffffffffffffffffffffffffffffffffff163314610a915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061083960b8836113bd565b6000610af16001611521565b90508015610b2657605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b2e611675565b610b37826113c9565b610bd161011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ba8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcc919061350d565b6114be565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610cab57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600067ffffffff00000000602084901b1663ffffffff8316175b9392505050565b60006107d260006116fa565b60006108397f00000000000000000000000000000000000000000000000000000000000000008361170d565b60855473ffffffffffffffffffffffffffffffffffffffff163314610d6f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b73ffffffffffffffffffffffffffffffffffffffff8116610df85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106f0565b61094581611795565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610e3757610e376132a9565b03610e845760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064016106f0565b61080081511115610ed75760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e67000000000000000000000000000000000000000060448201526064016106f0565b34610eef610ee48461180c565b62ffffff1916611819565b6bffffffffffffffffffffffff1614610f4a5760405162461bcd60e51b815260206004820152600560248201527f217469707300000000000000000000000000000000000000000000000000000060448201526064016106f0565b61011e54610f5f9063ffffffff16600161352a565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610fa08561187b565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e8301528051808303605201815260729092019052909150600061106a8286866118da565b8051602082012090915061107d81611954565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff1660016110ac60205490565b6110b691906134f6565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e78589866040516110e8929190613552565b60405180910390a4505050505050505050565b6000806111088382611984565b905060286bffffffffffffffffffffffff601883901c161161116c5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016106f0565b6111a061117e62ffffff1983166119a8565b61119b61119062ffffff1985166119bd565b62ffffff19166119f0565b611a43565b91506111ba6111b462ffffff198316611ac2565b8361170d565b6112065760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f746172790000000000000000000060448201526064016106f0565b915091565b600061083962ffffff198316600480611ad2565b600061083962ffffff19831660086020611b02565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156112ee57600080fd5b505af1158015611302573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610839825490565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146108a65760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e6765720000000000000000000000000000000060448201526064016106f0565b6000610cc98383611cc0565b73ffffffffffffffffffffffffffffffffffffffff81163b61142d5760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e61676572000000000000000060448201526064016106f0565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60606000610cc983611cea565b60006114cb60b883611d46565b905080156107c15760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff16156115c0578160ff1660011480156115465750303b155b6115b85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106f0565b506000919050565b60525460ff80841691161061163d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106f0565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166116f25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f0565b6108a6611d68565b600061083982611708611dee565b6122af565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461178a5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e000000000000000000000000000000000000000060448201526064016106f0565b610cc960b883612372565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610839826002611984565b60008161182f60025b62ffffff198316906123a1565b50611839836124a2565b611842846124d0565b61184b856124f1565b61185486612512565b61185e9190613577565b6118689190613577565b6118729190613577565b91505b50919050565b60007fffffffffffffffffffffffff000000000000000000000000000000000000000082146118ab573392915050565b6118b3611356565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906118ee6004600261359e565b60ff166118fb91906135c7565b9050600084518261190c91906135c7565b9050600161191c6004600261359e565b60ff16838389898960405160200161193a97969594939291906135e4565b604051602081830303815290604052925050509392505050565b61195f600082612533565b602161196b60006116fa565b8154600181018355600092835260209092209091015550565b81516000906020840161199f64ffffffffff85168284612656565b95945050505050565b600061083962ffffff1983168260288161269d565b600061083960286119e081601886901c6bffffffffffffffffffffffff166134f6565b62ffffff1985169190600061269d565b6060600080611a0d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506040519150819250611a328483602001612721565b508181016020016040529052919050565b600080611a5562ffffff1985166128bc565b9050611aae816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9050611aba8184612919565b949350505050565b600061083962ffffff1983168260045b6000611adf826020613682565b611aea90600861359e565b60ff16611af8858585611b02565b901c949350505050565b60008160ff16600003611b1757506000610cc9565b611b2f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611b4a60ff8416856136a5565b1115611bc257611ba9611b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611b918660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661293d565b60405162461bcd60e51b81526004016106f091906136bd565b60208260ff161115611c3c5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016106f0565b600882026000611c5a8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611cd757611cd76133ef565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611d3a57602002820191906000526020600020905b815481526020019060010190808311611d26575b50505050509050919050565b6000610cc98373ffffffffffffffffffffffffffffffffffffffff84166129ab565b605254610100900460ff16611de55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f0565b6108a633611795565b611df66130c9565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561236a57600182821c811690819003612316578582602081106122e3576122e36133ef565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612361565b83858360208110612329576123296133ef565b6020020151604051602001612348929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016122b9565b505092915050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610cc9565b60006123ad83836129fa565b61249b5760006123cc6123c08560d81c90565b64ffffffffff16612a1d565b91505060006123e18464ffffffffff16612a1d565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016106f091906136bd565b5090919050565b6000816124af6002611822565b506124c362ffffff1984166026600c611ad2565b63ffffffff169392505050565b6000816124dd6002611822565b506124c362ffffff198416601a600c611ad2565b6000816124fe6002611822565b506124c362ffffff198416600e600c611ad2565b60008161251f6002611822565b506124c362ffffff1984166002600c611ad2565b602080830154906001906125489060026137e8565b61255291906134f6565b81106125a05760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c0000000000000000000000000000000060448201526064016106f0565b6001016020830181905560005b602081101561264857816001166001036125dc57828482602081106125d4576125d46133ef565b015550505050565b8381602081106125ee576125ee6133ef565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016125ad565b506126516137f4565b505050565b60008061266383856136a5565b9050604051811115612673575060005b806000036126885762ffffff19915050610cc9565b5050606092831b9190911790911b1760181b90565b6000806126b88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506126d186612b07565b846126dc87846136a5565b6126e691906136a5565b11156126f95762ffffff19915050611aba565b61270385826136a5565b90506127178364ffffffffff168286612656565b9695505050505050565b600062ffffff198084160361279e5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016106f0565b6127a783612b4f565b6128195760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016106f0565b60006128338460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061285d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156128825760206060fd5b8285848460045afa506127176128988760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806128d78360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006129018460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006129288585612b8c565b9150915061293581612bfa565b509392505050565b6060600061294a86612a1d565b915050600061295886612a1d565b915050600061296686612a1d565b915050600061297486612a1d565b9150508383838360405160200161298e9493929190613823565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546129f257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610839565b506000610839565b60008164ffffffffff16612a0e8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115612a90576000612a3c82600861359e565b60ff1685901c9050612a4d81612de6565b61ffff16841793508160ff16601014612a6857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612a23565b50600f5b60ff8160ff161015612b01576000612aad82600861359e565b60ff1685901c9050612abe81612de6565b61ffff16831792508160ff16600014612ad957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612a94565b50915091565b6000612b218260181c6bffffffffffffffffffffffff1690565b612b398360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612b5b8260d81c90565b64ffffffffff1664ffffffffff03612b7557506000919050565b6000612b8083612b07565b60405110199392505050565b6000808251604103612bc25760208301516040840151606085015160001a612bb687828585612e18565b94509450505050612bf3565b8251604003612beb5760208301516040840151612be0868383612f30565b935093505050612bf3565b506000905060025b9250929050565b6000816004811115612c0e57612c0e6132a9565b03612c165750565b6001816004811115612c2a57612c2a6132a9565b03612c775760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106f0565b6002816004811115612c8b57612c8b6132a9565b03612cd85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106f0565b6003816004811115612cec57612cec6132a9565b03612d5f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016106f0565b6004816004811115612d7357612d736132a9565b036109455760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016106f0565b6000612df860048360ff16901c612f82565b60ff1661ffff919091161760081b612e0f82612f82565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612e4f5750600090506003612f27565b8460ff16601b14158015612e6757508460ff16601c14155b15612e785750600090506004612f27565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612ecc573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612f2057600060019250925050612f27565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612f6660ff86901c601b6136a5565b9050612f7487828885612e18565b935093505050935093915050565b600060f08083179060ff82169003612f9d5750603092915050565b8060ff1660f103612fb15750603192915050565b8060ff1660f203612fc55750603292915050565b8060ff1660f303612fd95750603392915050565b8060ff1660f403612fed5750603492915050565b8060ff1660f5036130015750603592915050565b8060ff1660f6036130155750603692915050565b8060ff1660f7036130295750603792915050565b8060ff1660f80361303d5750603892915050565b8060ff1660f9036130515750603992915050565b8060ff1660fa036130655750606192915050565b8060ff1660fb036130795750606292915050565b8060ff1660fc0361308d5750606392915050565b8060ff1660fd036130a15750606492915050565b8060ff1660fe036130b55750606592915050565b8060ff1660ff036118755750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261312857600080fd5b813567ffffffffffffffff80821115613143576131436130e8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613189576131896130e8565b816040528381528660208588010111156131a257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000602082840312156131d457600080fd5b813567ffffffffffffffff8111156131eb57600080fd5b611aba84828501613117565b60006020828403121561320957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461094557600080fd5b60006020828403121561324457600080fd5b8135610cc981613210565b6020808252825182820181905260009190848201906040850190845b8181101561329d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161326b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310613313577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146107c157600080fd5b6000806040838503121561334057600080fd5b61334983613319565b915061335760208401613319565b90509250929050565b600080600080600060a0868803121561337857600080fd5b61338186613319565b94506020860135935061339660408701613319565b9250606086013567ffffffffffffffff808211156133b357600080fd5b6133bf89838a01613117565b935060808801359150808211156133d557600080fd5b506133e288828901613117565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b83811015613439578181015183820152602001613421565b83811115613448576000848401525b50505050565b6000815180845261346681602086016020860161341e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aba604083018461344e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015613508576135086134c7565b500390565b60006020828403121561351f57600080fd5b8151610cc981613210565b600063ffffffff808316818516808303821115613549576135496134c7565b01949350505050565b604081526000613565604083018561344e565b828103602084015261199f818561344e565b60006bffffffffffffffffffffffff808316818516808303821115613549576135496134c7565b600060ff821660ff84168160ff04811182151516156135bf576135bf6134c7565b029392505050565b600061ffff808316818516808303821115613549576135496134c7565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b16600684015250845161364481600885016020890161341e565b84519083019061365b81600884016020890161341e565b845191019061367181600884016020880161341e565b016008019998505050505050505050565b600060ff821660ff84168082101561369c5761369c6134c7565b90039392505050565b600082198211156136b8576136b86134c7565b500190565b602081526000610cc9602083018461344e565b600181815b8085111561372957817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561370f5761370f6134c7565b8085161561371c57918102915b93841c93908002906136d5565b509250929050565b60008261374057506001610839565b8161374d57506000610839565b8160018114613763576002811461376d57613789565b6001915050610839565b60ff84111561377e5761377e6134c7565b50506001821b610839565b5060208310610133831016604e8410600b84101617156137ac575081810a610839565b6137b683836136d0565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156135bf576135bf6134c7565b6000610cc98383613731565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161271756fea264697066735822122009bcaead08729c8a3a797dab376fd9e8a037e4d92ffac1cbe9fe31c138d679fa64736f6c634300080d0033","runtime-code":"0x6080604052600436106101e35760003560e01c80639df6c8e111610102578063ccbdf9c911610095578063f2fde38b11610064578063f2fde38b146105fe578063f7560e401461061e578063fd54b22814610631578063ffa1ad741461064857600080fd5b8063ccbdf9c914610563578063da180e7014610590578063ebf0c717146105c9578063f13eed97146105de57600080fd5b8063b7bc563e116100d1578063b7bc563e146104bf578063c07dc7f5146104df578063c19d93fb146104ff578063c4d66de81461054357600080fd5b80639df6c8e1146104365780639fe03fa21461046c578063a1191a5114610481578063affed0e0146104a157600080fd5b8063715018a61161017a5780638e62e9ef116101495780638e62e9ef146103bf5780639776120e146103d45780639817e315146103f45780639d54f4191461041657600080fd5b8063715018a6146103165780637ea97f401461032b5780638d3638f41461034b5780638da5cb5b1461039457600080fd5b806336e104de116101b657806336e104de1461026857806348639d2414610299578063522ae002146102bb578063629ddf69146102d157600080fd5b806306661abd146101e8578063089d28941461020c5780630afe7f9014610223578063246c244914610253575b600080fd5b3480156101f457600080fd5b506020545b6040519081526020015b60405180910390f35b34801561021857600080fd5b506101f961014e5481565b34801561022f57600080fd5b5061024361023e3660046131c2565b61066f565b6040519015158152602001610203565b34801561025f57600080fd5b506101f96107c6565b34801561027457600080fd5b5061027d6107d7565b6040805163ffffffff9093168352602083019190915201610203565b3480156102a557600080fd5b506102b96102b43660046131f7565b61081e565b005b3480156102c757600080fd5b506101f961080081565b3480156102dd57600080fd5b506102f16102ec3660046131f7565b61082c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610203565b34801561032257600080fd5b506102b961083f565b34801561033757600080fd5b506101f96103463660046131f7565b6108a8565b34801561035757600080fd5b5061037f7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610203565b3480156103a057600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff166102f1565b3480156103cb57600080fd5b506101f96108c9565b3480156103e057600080fd5b506102b96103ef366004613232565b6108d5565b34801561040057600080fd5b50610409610948565b604051610203919061324f565b34801561042257600080fd5b506102b9610431366004613232565b610954565b34801561044257600080fd5b5061011e546102f190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561047857600080fd5b50610409610a15565b34801561048d57600080fd5b506102b961049c366004613232565b610a21565b3480156104ad57600080fd5b5061011e5461037f9063ffffffff1681565b3480156104cb57600080fd5b506102b96104da366004613232565b610a2a565b3480156104eb57600080fd5b506102f16104fa3660046131f7565b610ad8565b34801561050b57600080fd5b5061011e54610536907801000000000000000000000000000000000000000000000000900460ff1681565b60405161020391906132d8565b34801561054f57600080fd5b506102b961055e366004613232565b610ae5565b34801561056f57600080fd5b5060b7546102f19073ffffffffffffffffffffffffffffffffffffffff1681565b34801561059c57600080fd5b506105b06105ab36600461332d565b610caf565b60405167ffffffffffffffff9091168152602001610203565b3480156105d557600080fd5b506101f9610cd0565b3480156105ea57600080fd5b506102436105f9366004613232565b610cdc565b34801561060a57600080fd5b506102b9610619366004613232565b610d08565b6102b961062c366004613360565b610e01565b34801561063d57600080fd5b506020546101f99081565b34801561065457600080fd5b5061065d600081565b60405160ff9091168152602001610203565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156106a7576106a76132a9565b036106f95760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600080610705846110fb565b91509150600061071a8262ffffff191661120b565b9050600061072d62ffffff19841661121f565b60215490915063ffffffff831610156107765760218263ffffffff1681548110610759576107596133ef565b906000526020600020015481036107765750600095945050505050565b61077f84611234565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516107b0929190613498565b60405180910390a160019450505050505b919050565b60006107d260eb61134c565b905090565b60215460009081908015610819576107f06001826134f6565b925060218363ffffffff168154811061080b5761080b6133ef565b906000526020600020015491505b509091565b610826611356565b61014e55565b600061083960eb836113bd565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b565b602181815481106108b857600080fd5b600091825260209091200154905081565b60006107d260b861134c565b60855473ffffffffffffffffffffffffffffffffffffffff16331461093c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b610945816113c9565b50565b60606107d260b86114b1565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146109c45760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e61676572000000000000000000000000000000000060448201526064016106f0565b6109cd816114be565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606107d260eb6114b1565b61094581611234565b60855473ffffffffffffffffffffffffffffffffffffffff163314610a915760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061083960b8836113bd565b6000610af16001611521565b90508015610b2657605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610b2e611675565b610b37826113c9565b610bd161011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ba8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcc919061350d565b6114be565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610cab57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600067ffffffff00000000602084901b1663ffffffff8316175b9392505050565b60006107d260006116fa565b60006108397f00000000000000000000000000000000000000000000000000000000000000008361170d565b60855473ffffffffffffffffffffffffffffffffffffffff163314610d6f5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106f0565b73ffffffffffffffffffffffffffffffffffffffff8116610df85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016106f0565b61094581611795565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610e3757610e376132a9565b03610e845760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064016106f0565b61080081511115610ed75760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e67000000000000000000000000000000000000000060448201526064016106f0565b34610eef610ee48461180c565b62ffffff1916611819565b6bffffffffffffffffffffffff1614610f4a5760405162461bcd60e51b815260206004820152600560248201527f217469707300000000000000000000000000000000000000000000000000000060448201526064016106f0565b61011e54610f5f9063ffffffff16600161352a565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610fa08561187b565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e8301528051808303605201815260729092019052909150600061106a8286866118da565b8051602082012090915061107d81611954565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff1660016110ac60205490565b6110b691906134f6565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e78589866040516110e8929190613552565b60405180910390a4505050505050505050565b6000806111088382611984565b905060286bffffffffffffffffffffffff601883901c161161116c5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016106f0565b6111a061117e62ffffff1983166119a8565b61119b61119062ffffff1985166119bd565b62ffffff19166119f0565b611a43565b91506111ba6111b462ffffff198316611ac2565b8361170d565b6112065760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f746172790000000000000000000060448201526064016106f0565b915091565b600061083962ffffff198316600480611ad2565b600061083962ffffff19831660086020611b02565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156112ee57600080fd5b505af1158015611302573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610839825490565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146108a65760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e6765720000000000000000000000000000000060448201526064016106f0565b6000610cc98383611cc0565b73ffffffffffffffffffffffffffffffffffffffff81163b61142d5760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e61676572000000000000000060448201526064016106f0565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60606000610cc983611cea565b60006114cb60b883611d46565b905080156107c15760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff16156115c0578160ff1660011480156115465750303b155b6115b85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106f0565b506000919050565b60525460ff80841691161061163d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016106f0565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166116f25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f0565b6108a6611d68565b600061083982611708611dee565b6122af565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461178a5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e000000000000000000000000000000000000000060448201526064016106f0565b610cc960b883612372565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610839826002611984565b60008161182f60025b62ffffff198316906123a1565b50611839836124a2565b611842846124d0565b61184b856124f1565b61185486612512565b61185e9190613577565b6118689190613577565b6118729190613577565b91505b50919050565b60007fffffffffffffffffffffffff000000000000000000000000000000000000000082146118ab573392915050565b6118b3611356565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906118ee6004600261359e565b60ff166118fb91906135c7565b9050600084518261190c91906135c7565b9050600161191c6004600261359e565b60ff16838389898960405160200161193a97969594939291906135e4565b604051602081830303815290604052925050509392505050565b61195f600082612533565b602161196b60006116fa565b8154600181018355600092835260209092209091015550565b81516000906020840161199f64ffffffffff85168284612656565b95945050505050565b600061083962ffffff1983168260288161269d565b600061083960286119e081601886901c6bffffffffffffffffffffffff166134f6565b62ffffff1985169190600061269d565b6060600080611a0d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506040519150819250611a328483602001612721565b508181016020016040529052919050565b600080611a5562ffffff1985166128bc565b9050611aae816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b9050611aba8184612919565b949350505050565b600061083962ffffff1983168260045b6000611adf826020613682565b611aea90600861359e565b60ff16611af8858585611b02565b901c949350505050565b60008160ff16600003611b1757506000610cc9565b611b2f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611b4a60ff8416856136a5565b1115611bc257611ba9611b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611b918660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661293d565b60405162461bcd60e51b81526004016106f091906136bd565b60208260ff161115611c3c5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016106f0565b600882026000611c5a8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611cd757611cd76133ef565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611d3a57602002820191906000526020600020905b815481526020019060010190808311611d26575b50505050509050919050565b6000610cc98373ffffffffffffffffffffffffffffffffffffffff84166129ab565b605254610100900460ff16611de55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016106f0565b6108a633611795565b611df66130c9565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561236a57600182821c811690819003612316578582602081106122e3576122e36133ef565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612361565b83858360208110612329576123296133ef565b6020020151604051602001612348929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016122b9565b505092915050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610cc9565b60006123ad83836129fa565b61249b5760006123cc6123c08560d81c90565b64ffffffffff16612a1d565b91505060006123e18464ffffffffff16612a1d565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016106f091906136bd565b5090919050565b6000816124af6002611822565b506124c362ffffff1984166026600c611ad2565b63ffffffff169392505050565b6000816124dd6002611822565b506124c362ffffff198416601a600c611ad2565b6000816124fe6002611822565b506124c362ffffff198416600e600c611ad2565b60008161251f6002611822565b506124c362ffffff1984166002600c611ad2565b602080830154906001906125489060026137e8565b61255291906134f6565b81106125a05760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c0000000000000000000000000000000060448201526064016106f0565b6001016020830181905560005b602081101561264857816001166001036125dc57828482602081106125d4576125d46133ef565b015550505050565b8381602081106125ee576125ee6133ef565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016125ad565b506126516137f4565b505050565b60008061266383856136a5565b9050604051811115612673575060005b806000036126885762ffffff19915050610cc9565b5050606092831b9190911790911b1760181b90565b6000806126b88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506126d186612b07565b846126dc87846136a5565b6126e691906136a5565b11156126f95762ffffff19915050611aba565b61270385826136a5565b90506127178364ffffffffff168286612656565b9695505050505050565b600062ffffff198084160361279e5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016106f0565b6127a783612b4f565b6128195760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016106f0565b60006128338460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061285d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156128825760206060fd5b8285848460045afa506127176128988760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806128d78360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006129018460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006129288585612b8c565b9150915061293581612bfa565b509392505050565b6060600061294a86612a1d565b915050600061295886612a1d565b915050600061296686612a1d565b915050600061297486612a1d565b9150508383838360405160200161298e9493929190613823565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546129f257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610839565b506000610839565b60008164ffffffffff16612a0e8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115612a90576000612a3c82600861359e565b60ff1685901c9050612a4d81612de6565b61ffff16841793508160ff16601014612a6857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612a23565b50600f5b60ff8160ff161015612b01576000612aad82600861359e565b60ff1685901c9050612abe81612de6565b61ffff16831792508160ff16600014612ad957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612a94565b50915091565b6000612b218260181c6bffffffffffffffffffffffff1690565b612b398360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612b5b8260d81c90565b64ffffffffff1664ffffffffff03612b7557506000919050565b6000612b8083612b07565b60405110199392505050565b6000808251604103612bc25760208301516040840151606085015160001a612bb687828585612e18565b94509450505050612bf3565b8251604003612beb5760208301516040840151612be0868383612f30565b935093505050612bf3565b506000905060025b9250929050565b6000816004811115612c0e57612c0e6132a9565b03612c165750565b6001816004811115612c2a57612c2a6132a9565b03612c775760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106f0565b6002816004811115612c8b57612c8b6132a9565b03612cd85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106f0565b6003816004811115612cec57612cec6132a9565b03612d5f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016106f0565b6004816004811115612d7357612d736132a9565b036109455760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016106f0565b6000612df860048360ff16901c612f82565b60ff1661ffff919091161760081b612e0f82612f82565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612e4f5750600090506003612f27565b8460ff16601b14158015612e6757508460ff16601c14155b15612e785750600090506004612f27565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612ecc573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612f2057600060019250925050612f27565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612f6660ff86901c601b6136a5565b9050612f7487828885612e18565b935093505050935093915050565b600060f08083179060ff82169003612f9d5750603092915050565b8060ff1660f103612fb15750603192915050565b8060ff1660f203612fc55750603292915050565b8060ff1660f303612fd95750603392915050565b8060ff1660f403612fed5750603492915050565b8060ff1660f5036130015750603592915050565b8060ff1660f6036130155750603692915050565b8060ff1660f7036130295750603792915050565b8060ff1660f80361303d5750603892915050565b8060ff1660f9036130515750603992915050565b8060ff1660fa036130655750606192915050565b8060ff1660fb036130795750606292915050565b8060ff1660fc0361308d5750606392915050565b8060ff1660fd036130a15750606492915050565b8060ff1660fe036130b55750606592915050565b8060ff1660ff036118755750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261312857600080fd5b813567ffffffffffffffff80821115613143576131436130e8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613189576131896130e8565b816040528381528660208588010111156131a257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000602082840312156131d457600080fd5b813567ffffffffffffffff8111156131eb57600080fd5b611aba84828501613117565b60006020828403121561320957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461094557600080fd5b60006020828403121561324457600080fd5b8135610cc981613210565b6020808252825182820181905260009190848201906040850190845b8181101561329d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161326b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310613313577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146107c157600080fd5b6000806040838503121561334057600080fd5b61334983613319565b915061335760208401613319565b90509250929050565b600080600080600060a0868803121561337857600080fd5b61338186613319565b94506020860135935061339660408701613319565b9250606086013567ffffffffffffffff808211156133b357600080fd5b6133bf89838a01613117565b935060808801359150808211156133d557600080fd5b506133e288828901613117565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b83811015613439578181015183820152602001613421565b83811115613448576000848401525b50505050565b6000815180845261346681602086016020860161341e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611aba604083018461344e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015613508576135086134c7565b500390565b60006020828403121561351f57600080fd5b8151610cc981613210565b600063ffffffff808316818516808303821115613549576135496134c7565b01949350505050565b604081526000613565604083018561344e565b828103602084015261199f818561344e565b60006bffffffffffffffffffffffff808316818516808303821115613549576135496134c7565b600060ff821660ff84168160ff04811182151516156135bf576135bf6134c7565b029392505050565b600061ffff808316818516808303821115613549576135496134c7565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b16600684015250845161364481600885016020890161341e565b84519083019061365b81600884016020890161341e565b845191019061367181600884016020880161341e565b016008019998505050505050505050565b600060ff821660ff84168082101561369c5761369c6134c7565b90039392505050565b600082198211156136b8576136b86134c7565b500190565b602081526000610cc9602083018461344e565b600181815b8085111561372957817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561370f5761370f6134c7565b8085161561371c57918102915b93841c93908002906136d5565b509250929050565b60008261374057506001610839565b8161374d57506000610839565b8160018114613763576002811461376d57613789565b6001915050610839565b60ff84111561377e5761377e6134c7565b50506001821b610839565b5060208310610133831016604e8410600b84101617156137ac575081810a610839565b6137b683836136d0565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156135bf576135bf6134c7565b6000610cc98383613731565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161271756fea264697066735822122009bcaead08729c8a3a797dab376fd9e8a037e4d92ffac1cbe9fe31c138d679fa64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"137687:610:0:-:0;;;137758:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113030:26;;;;;;62691:30;;137687:610;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;137687:610:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"137687:610:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116729:81;;;;;;;;;;-1:-1:-1;116793:10:0;;116729:81;;;160:25:1;;;148:2;133:18;116729:81:0;;;;;;;;137722:29;;;;;;;;;;;;;;;;134209:780;;;;;;;;;;-1:-1:-1;134209:780:0;;;;;:::i;:::-;;:::i;:::-;;;1657:14:1;;1650:22;1632:41;;1620:2;1605:18;134209:780:0;1492:187:1;67835:95:0;;;;;;;;;;;;;:::i;132658:257::-;;;;;;;;;;;;;:::i;:::-;;;;1886:10:1;1874:23;;;1856:42;;1929:2;1914:18;;1907:34;;;;1829:18;132658:257:0;1684:263:1;137931:118:0;;;;;;;;;;-1:-1:-1;137931:118:0;;;;;:::i;:::-;;:::i;:::-;;126214:58;;;;;;;;;;;;126263:9;126214:58;;67722:107;;;;;;;;;;-1:-1:-1;67722:107:0;;;;;:::i;:::-;;:::i;:::-;;;2313:42:1;2301:55;;;2283:74;;2271:2;2256:18;67722:107:0;2137:226:1;115346:57:0;;;;;;;;;;;;;:::i;116273:32::-;;;;;;;;;;-1:-1:-1;116273:32:0;;;;;:::i;:::-;;:::i;111819:35::-;;;;;;;;;;;;;;;;;;2724:10:1;2712:23;;;2694:42;;2682:2;2667:18;111819:35:0;2550:192:1;109502:85:0;;;;;;;;;;-1:-1:-1;109574:6:0;;;;109502:85;;63501:99;;;;;;;;;;;;;:::i;130299:140::-;;;;;;;;;;-1:-1:-1;130299:140:0;;;;;:::i;:::-;;:::i;63274:105::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;129627:253::-;;;;;;;;;;-1:-1:-1;129627:253:0;;;;;:::i;:::-;;:::i;126487:37::-;;;;;;;;;;-1:-1:-1;126487:37:0;;;;;;;;;;;67615:101;;;;;;;;;;;;;:::i;138055:74::-;;;;;;;;;;-1:-1:-1;138055:74:0;;;;;:::i;:::-;;:::i;126391:19::-;;;;;;;;;;-1:-1:-1;126391:19:0;;;;;;;;115020:133;;;;;;;;;;-1:-1:-1;115020:133:0;;;;;:::i;:::-;;:::i;63385:110::-;;;;;;;;;;-1:-1:-1;63385:110:0;;;;;:::i;:::-;;:::i;126563:19::-;;;;;;;;;;-1:-1:-1;126563:19:0;;;;;;;;;;;;;;;;;;:::i;128573:354::-;;;;;;;;;;-1:-1:-1;128573:354:0;;;;;:::i;:::-;;:::i;112401:39::-;;;;;;;;;;-1:-1:-1;112401:39:0;;;;;;;;138135:160;;;;;;;;;;-1:-1:-1;138135:160:0;;;;;:::i;:::-;;:::i;:::-;;;6101:18:1;6089:31;;;6071:50;;6059:2;6044:18;138135:160:0;5927:200:1;116545:81:0;;;;;;;;;;;;;:::i;137808:117::-;;;;;;;;;;-1:-1:-1;137808:117:0;;;;;:::i;:::-;;:::i;110384:198::-;;;;;;;;;;-1:-1:-1;110384:198:0;;;;;:::i;:::-;;:::i;130945:1473::-;;;;;;:::i;:::-;;:::i;116241:26::-;;;;;;;;;;-1:-1:-1;116241:26:0;;;;;;50:33;;;;;;;;;;;;82:1;50:33;;;;;7062:4:1;7050:17;;;7032:36;;7020:2;7005:18;50:33:0;6890:184:1;134209:780:0;134291:4;129345:13;129336:5;;;;;;;:22;;;;;;;;:::i;:::-;;129328:47;;;;-1:-1:-1;;;129328:47:0;;7281:2:1;129328:47:0;;;7263:21:1;7320:2;7300:18;;;7293:30;7359:14;7339:18;;;7332:42;7391:18;;129328:47:0;;;;;;;;;134362:15:::1;134379:13:::0;134396:30:::1;134413:12;134396:16;:30::i;:::-;134361:65;;;;134436:13;134452:24;:5;:22;;;;:24::i;:::-;134436:40:::0;-1:-1:-1;134486:13:0::1;134502:23;-1:-1:-1::0;;134502:21:0;::::1;;:23::i;:::-;134610:15;:22:::0;134486:39;;-1:-1:-1;134601:31:0::1;::::0;::::1;;134597:284;;;134661:15;134677:6;134661:23;;;;;;;;;;:::i;:::-;;;;;;;;;134652:5;:32:::0;134648:139:::1;;-1:-1:-1::0;134767:5:0::1;::::0;134209:780;-1:-1:-1;;;;;134209:780:0:o;134648:139::-:1;134890:14;134896:7;134890:5;:14::i;:::-;134919:42;134939:7;134948:12;134919:42;;;;;;;:::i;:::-;;;;;;;;134978:4;134971:11;;;;;;129385:1;134209:780:::0;;;:::o;67835:95::-;67882:7;67908:15;:6;:13;:15::i;:::-;67901:22;;67835:95;:::o;132658:257::-;132763:15;:22;132706:13;;;;132799:11;;132795:114;;132842:10;132851:1;132842:6;:10;:::i;:::-;132826:27;;132875:15;132891:6;132875:23;;;;;;;;;;:::i;:::-;;;;;;;;;132867:31;;132795:114;132736:179;132658:257;;:::o;137931:118::-;114432:24;:22;:24::i;:::-;138016:14:::1;:26:::0;137931:118::o;67722:107::-;67779:7;67805:17;:6;67815;67805:9;:17::i;:::-;67798:24;67722:107;-1:-1:-1;;67722:107:0:o;115346:57::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;9056:2:1;109706:68:0;;;9038:21:1;;;9075:18;;;9068:30;9134:34;9114:18;;;9107:62;9186:18;;109706:68:0;8854:356:1;109706:68:0;115346:57::o;116273:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116273:32:0;:::o;63501:99::-;63550:7;63576:17;:8;:15;:17::i;130299:140::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;9056:2:1;109706:68:0;;;9038:21:1;;;9075:18;;;9068:30;9134:34;9114:18;;;9107:62;9186:18;;109706:68:0;8854:356:1;109706:68:0;130380:52:::1;130415:15;130380:18;:52::i;:::-;130299:140:::0;:::o;63274:105::-;63320:16;63355:17;:8;:15;:17::i;129627:253::-;129141:14;;;;;;;129119:10;:37;129111:65;;;;-1:-1:-1;;;129111:65:0;;9417:2:1;129111:65:0;;;9399:21:1;9456:2;9436:18;;;9429:30;9495:17;9475:18;;;9468:45;9530:18;;129111:65:0;9215:339:1;129111:65:0;129737:20:::1;129748:8;129737:10;:20::i;:::-;-1:-1:-1::0;;129852:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;129627:253::o;67615:101::-;67659:16;67694:15;:6;:13;:15::i;138055:74::-;138108:14;138114:7;138108:5;:14::i;115020:133::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;9056:2:1;109706:68:0;;;9038:21:1;;;9075:18;;;9068:30;9134:34;9114:18;;;9107:62;9186:18;;109706:68:0;8854:356:1;109706:68:0;115112:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;115020:133::o;63385:110::-;63443:7;63469:19;:8;63481:6;63469:11;:19::i;128573:354::-;104682:19;104704:25;104727:1;104704:22;:25::i;:::-;104682:47;;104743:14;104739:65;;;104773:13;:20;;;;;;;;104739:65;128655:29:::1;:27;:29::i;:::-;128694:35;128713:15;128694:18;:35::i;:::-;128739:36;128750:14;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;128739:10;:36::i;:::-;-1:-1:-1::0;128785:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;128887:15:::1;:33:::0;;-1:-1:-1;128887:33:0;::::1;::::0;;-1:-1:-1;128887:33:0;;;;::::1;::::0;104824:99;;;;104858:13;:21;;;;;;104898:14;;-1:-1:-1;7032:36:1;;104898:14:0;;7020:2:1;7005:18;104898:14:0;;;;;;;104824:99;104672:257;128573:354;:::o;138135:160::-;138221:6;136393:26;136417:2;136393:26;;;;136392:37;;;;138246:42;138239:49;138135:160;-1:-1:-1;;;138135:160:0:o;116545:81::-;116582:7;116608:11;:4;:9;:11::i;137808:117::-;137864:4;137887:31;137897:11;137910:7;137887:9;:31::i;110384:198::-;109574:6;;109714:23;109574:6;108502:10;109714:23;109706:68;;;;-1:-1:-1;;;109706:68:0;;9056:2:1;109706:68:0;;;9038:21:1;;;9075:18;;;9068:30;9134:34;9114:18;;;9107:62;9186:18;;109706:68:0;8854:356:1;109706:68:0;110472:22:::1;::::0;::::1;110464:73;;;::::0;-1:-1:-1;;;110464:73:0;;10216:2:1;110464:73:0::1;::::0;::::1;10198:21:1::0;10255:2;10235:18;;;10228:30;10294:34;10274:18;;;10267:62;10365:8;10345:18;;;10338:36;10391:19;;110464:73:0::1;10014:402:1::0;110464:73:0::1;110547:28;110566:8;110547:18;:28::i;130945:1473::-:0;129345:13;129336:5;;;;;;;:22;;;;;;;;:::i;:::-;;129328:47;;;;-1:-1:-1;;;129328:47:0;;7281:2:1;129328:47:0;;;7263:21:1;7320:2;7300:18;;;7293:30;7359:14;7339:18;;;7332:42;7391:18;;129328:47:0;7079:336:1;129328:47:0;126263:9:::1;131182:12;:19;:45;;131174:70;;;::::0;-1:-1:-1;;;131174:70:0;;10623:2:1;131174:70:0::1;::::0;::::1;10605:21:1::0;10662:2;10642:18;;;10635:30;10701:14;10681:18;;;10674:42;10733:18;;131174:70:0::1;10421:336:1::0;131174:70:0::1;131294:9;131262:28;:16;:5;:14;:16::i;:::-;-1:-1:-1::0;;131262:26:0::1;;:28::i;:::-;:41;;;131254:59;;;::::0;-1:-1:-1;;;131254:59:0;;10964:2:1;131254:59:0::1;::::0;::::1;10946:21:1::0;11003:1;10983:18;;;10976:29;11041:7;11021:18;;;11014:35;11066:18;;131254:59:0::1;10762:328:1::0;131254:59:0::1;131407:5;::::0;:9:::1;::::0;:5:::1;;::::0;:9:::1;:::i;:::-;131399:5;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;131444:41:0::1;131467:17:::0;131444:22:::1;:41::i;:::-;131645:5;::::0;79428:242;;;15073:16:1;79428:242:0;;;15057:102:1;15178:66;131599:11:0::1;15281:3:1::0;15277:16;;;15273:25;;15260:11;;;15253:46;15315:11;;;15308:27;;;15369:16;;;;;15351:12;;;15344:47;15425:16;;;15421:25;;15407:12;;;15400:47;15463:12;;;15456:28;;;15518:16;;;;15514:25;;;15500:12;;;15493:47;79428:242:0;;;;;;;;;15556:12:1;;;;79428:242:0;;131426:59;;-1:-1:-1;131813:21:0::1;131837:51;131859:7;131868:5;131875:12;131837:21;:51::i;:::-;131979:19:::0;;::::1;::::0;::::1;::::0;131813:75;;-1:-1:-1;132061:25:0::1;131979:19:::0;132061:11:::1;:25::i;:::-;132354:5;::::0;::::1;;136417:2:::0;136393:26;;;;;136392:37;132240:171:::1;;132298:1;132288:7;116793:10:::0;;;116729:81;132288:7:::1;:11;;;;:::i;:::-;132262:12;132240:171;132374:5;132393:8;132240:171;;;;;;;:::i;:::-;;;;;;;;131164:1254;;;;130945:1473:::0;;;;;:::o;47614:470::-;47714:16;;47769:19;:12;47714:16;47769;:19::i;:::-;47761:27;-1:-1:-1;33025:2:0;2732:26;16554:2;16550:16;;;16546:28;34279:37;47798:52;;;;-1:-1:-1;;;47798:52:0;;11912:2:1;47798:52:0;;;11894:21:1;11951:2;11931:18;;;11924:30;11990:20;11970:18;;;11963:48;12028:18;;47798:52:0;11710:342:1;47798:52:0;47871:115;47903:23;-1:-1:-1;;47903:21:0;;;:23::i;:::-;47940:36;:28;-1:-1:-1;;47940:26:0;;;:28::i;:::-;-1:-1:-1;;47940:34:0;;:36::i;:::-;47871:18;:115::i;:::-;47860:126;-1:-1:-1;48004:46:0;48014:25;-1:-1:-1;;48014:23:0;;;:25::i;:::-;48041:8;48004:9;:46::i;:::-;47996:81;;;;-1:-1:-1;;;47996:81:0;;12259:2:1;47996:81:0;;;12241:21:1;12298:2;12278:18;;;12271:30;12337:24;12317:18;;;12310:52;12379:18;;47996:81:0;12057:346:1;47996:81:0;47614:470;;;:::o;34677:136::-;34741:6;34773:32;-1:-1:-1;;34773:15:0;;32919:1;;34773:15;:32::i;34906:124::-;34969:7;34995:28;-1:-1:-1;;34995:11:0;;32966:1;35020:2;34995:11;:28::i;135611:283::-;135733:5;:21;;;;;;;;;;;;135789:48;;;;;135825:10;135789:14;:48;;2283:74:1;135789:14:0;;;;;;;;;;:27;;2256:18:1;;135789:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;135852:35:0;;135876:10;;-1:-1:-1;135852:35:0;;;;-1:-1:-1;135852:35:0;;;;;135611:283;:::o;55788:115::-;55851:7;55877:19;55885:3;51403:18;;51321:107;115988:132;116076:15;;;;116054:10;:38;116046:67;;;;-1:-1:-1;;;116046:67:0;;12857:2:1;116046:67:0;;;12839:21:1;12896:2;12876:18;;;12869:30;12935:18;12915;;;12908:46;12971:18;;116046:67:0;12655:340:1;56245:156:0;56319:7;56369:22;56373:3;56385:5;56369:3;:22::i;135163:285::-;118516:19;;;;135243:81;;;;-1:-1:-1;;;135243:81:0;;13202:2:1;135243:81:0;;;13184:21:1;13241:2;13221:18;;;13214:30;13280:26;13260:18;;;13253:54;13324:18;;135243:81:0;13000:348:1;135243:81:0;135334:14;:49;;;;;;;;;;;;;;;;;;135398:43;;2283:74:1;;;135398:43:0;;2271:2:1;2256:18;135398:43:0;;;;;;;135163:285;:::o;56941:257::-;57004:16;57032:22;57057:19;57065:3;57057:7;:19::i;64146:207::-;64201:16;64243:21;:8;64256:7;64243:12;:21::i;:::-;64229:35;;64278:11;64274:73;;;64310:26;;2313:42:1;2301:55;;2283:74;;64310:26:0;;2271:2:1;2256:18;64310:26:0;;;;;;;64146:207;;;:::o;106858:808::-;107255:13;;106922:4;;107255:13;;;;;107251:409;;;107309:7;:12;;107320:1;107309:12;:61;;;;-1:-1:-1;107364:4:0;118516:19;:23;107309:61;107284:166;;;;-1:-1:-1;;;107284:166:0;;13555:2:1;107284:166:0;;;13537:21:1;13594:2;13574:18;;;13567:30;13633:34;13613:18;;;13606:62;13704:16;13684:18;;;13677:44;13738:19;;107284:166:0;13353:410:1;107284:166:0;-1:-1:-1;107471:5:0;;106858:808;-1:-1:-1;106858:808:0:o;107251:409::-;107515:12;;:22;;;;:12;;:22;107507:81;;;;-1:-1:-1;;;107507:81:0;;13555:2:1;107507:81:0;;;13537:21:1;13594:2;13574:18;;;13567:30;13633:34;13613:18;;;13606:62;13704:16;13684:18;;;13677:44;13738:19;;107507:81:0;13353:410:1;107507:81:0;-1:-1:-1;107602:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;106858:808:0:o;113609:108::-;106269:13;;;;;;;106261:69;;;;-1:-1:-1;;;106261:69:0;;13970:2:1;106261:69:0;;;13952:21:1;14009:2;13989:18;;;13982:30;14048:34;14028:18;;;14021:62;14119:13;14099:18;;;14092:41;14150:19;;106261:69:0;13768:407:1;106261:69:0;113684:26:::1;:24;:26::i;71146:122::-:0;71203:7;71229:32;71241:5;71248:12;:10;:12::i;:::-;71229:11;:32::i;64586:199::-;64670:4;64705:13;64694:24;;:7;:24;;;64686:49;;;;-1:-1:-1;;;64686:49:0;;14382:2:1;64686:49:0;;;14364:21:1;14421:2;14401:18;;;14394:30;14460:14;14440:18;;;14433:42;14492:18;;64686:49:0;14180:336:1;64686:49:0;64752:26;:8;64770:7;64752:17;:26::i;110736:187::-;110828:6;;;;110844:17;;;;;;;;;;;110876:40;;110828:6;;;110844:17;110828:6;;110876:40;;110809:16;;110876:40;110799:124;110736:187;:::o;88128:122::-;88189:7;88215:28;:5;82150:10;88215:9;:28::i;89235:183::-;89308:6;89292:5;87135:35;82150:10;82143:18;-1:-1:-1;;87135:16:0;;;;:35::i;:::-;;89392:19:::1;89405:5;89392:12;:19::i;:::-;89373:16;89383:5;89373:9;:16::i;:::-;89353:17;89364:5;89353:10;:17::i;:::-;89333;89344:5;89333:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;89326:85;;87180:1;89235:183:::0;;;;:::o;136865:814::-;136971:14;90053:24;137005:48;;137001:672;;137105:10;137069:47;134209:780;-1:-1:-1;;134209:780:0:o;137001:672::-;137509:24;:22;:24::i;:::-;-1:-1:-1;90053:24:0;136865:814;;;:::o;83335:638::-;83631:14;;83480:12;;83588:17;;83086:29;83104:10;82957:1;83086:29;:::i;:::-;83608:13;;:38;;;;:::i;:::-;83588:58;;83656:17;83696:5;:12;83676:10;:33;;;;:::i;:::-;83656:53;-1:-1:-1;81807:1:0;83086:29;83104:10;82957:1;83086:29;:::i;:::-;83805:13;;83836:10;83864;83892:7;83917:5;83940:12;83738:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83719:247;;;;83335:638;;;;;:::o;116967:123::-;117022:18;:4;117034:5;117022:11;:18::i;:::-;117050:15;117071:11;:4;:9;:11::i;:::-;117050:33;;;;;;;-1:-1:-1;117050:33:0;;;;;;;;;;;-1:-1:-1;116967:123:0:o;13717:359::-;13821:10;;13787:7;;13968:4;13959:14;;14043:26;;;;13959:14;13821:10;14043:5;:26::i;:::-;14036:33;13717:359;-1:-1:-1;;;;;13717:359:0:o;35136:155::-;35199:7;35225:59;-1:-1:-1;;35225:11:0;;35199:7;33025:2;35199:7;35225:11;:59::i;35374:172::-;35442:7;35468:71;33025:2;35498:37;33025:2;16554;16550:16;;;2732:26;16546:28;35498:37;:::i;:::-;-1:-1:-1;;35468:11:0;;;:71;35537:1;35468:11;:71::i;28370:632::-;28425:16;28453:11;28474:12;28489;28493:7;16554:2;16550:16;2732:26;16546:28;;16308:282;28489:12;28474:27;;;;28611:4;28605:11;28598:18;;28666:3;28659:10;;28712:33;28725:7;28734:3;28740:4;28734:10;28712:12;:33::i;:::-;-1:-1:-1;28869:14:0;;;28885:4;28865:25;28859:4;28852:39;28932:17;;28370:632;;-1:-1:-1;28370:632:0:o;46778:285::-;46888:14;;46935;-1:-1:-1;;46935:12:0;;;:14::i;:::-;46918:31;;46968:36;46997:6;45371:58;;22137:66:1;45371:58:0;;;22125:79:1;22220:12;;;22213:28;;;45241:7:0;;22257:12:1;;45371:58:0;;;;;;;;;;;;45361:69;;;;;;45354:76;;45172:265;;;;46968:36;46959:45;;47023:33;47037:6;47045:10;47023:13;:33::i;:::-;47014:42;46778:285;-1:-1:-1;;;;46778:285:0:o;34420:143::-;34485:6;34517:38;-1:-1:-1;;34517:15:0;;34485:6;34553:1;21183:221;21302:14;21380:11;21385:6;21380:2;:11;:::i;:::-;21379:17;;21395:1;21379:17;:::i;:::-;21335:62;;21343:30;21349:7;21358:6;21366;21343:5;:30::i;:::-;21335:62;;;21183:221;-1:-1:-1;;;;21183:221:0:o;20066:771::-;20181:14;20211:6;:11;;20221:1;20211:11;20207:59;;-1:-1:-1;20253:1:0;20238:17;;20207:59;20297:12;20301:7;16554:2;16550:16;2732:26;16546:28;;16308:282;20297:12;20279:30;;:15;;;;:6;:15;:::i;:::-;:30;20275:137;;;20332:68;20348:12;20352:7;15448:3;15444:17;2732:26;15440:29;;15121:364;20348:12;20332:68;;20362:12;20366:7;16554:2;16550:16;2732:26;16546:28;;16308:282;20362:12;20332:68;;20376:6;20392;20384:15;;20332;:68::i;:::-;20325:76;;-1:-1:-1;;;20325:76:0;;;;;;;;:::i;20275:137::-;20439:2;20429:6;:12;;;;20421:83;;;;-1:-1:-1;;;20421:83:0;;17888:2:1;20421:83:0;;;17870:21:1;17927:2;17907:18;;;17900:30;17966:34;17946:18;;;17939:62;18037:28;18017:18;;;18010:56;18083:19;;20421:83:0;17686:422:1;20421:83:0;20585:1;20576:10;;20515:15;20621:12;20625:7;15448:3;15444:17;2732:26;15440:29;;15121:364;20621:12;20606:27;;;-1:-1:-1;20643:13:0;7550:66;7520:12;;;7499:131;20795:17;;;;20789:24;20785:36;;;-1:-1:-1;;;;;20066:771:0:o;51770:118::-;51837:7;51863:3;:11;;51875:5;51863:18;;;;;;;;:::i;:::-;;;;;;;;;51856:25;;51770:118;;;;:::o;52428:109::-;52484:16;52519:3;:11;;52512:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52428:109;;;:::o;54987:150::-;55057:4;55080:50;55085:3;55105:23;;;55080:4;:50::i;109315:111::-;106269:13;;;;;;;106261:69;;;;-1:-1:-1;;;106261:69:0;;13970:2:1;106261:69:0;;;13952:21:1;14009:2;13989:18;;;13982:30;14048:34;14028:18;;;14021:62;14119:13;14099:18;;;14092:41;14150:19;;106261:69:0;13768:407:1;106261:69:0;109387:32:::1;108502:10:::0;109387:18:::1;:32::i;71386:964::-:0;71431:34;;:::i;:::-;71490:3;71477:16;;71516:3;71477:10;71503;;:16;71542:3;71529:10;;;:16;71568:3;71555:10;;;:16;71594:3;71581:10;;;:16;71620:3;71607:10;;;:16;71646:3;71633:10;;;:16;71672:3;71659:10;;;:16;71698:3;71685:10;;;:16;71724:3;71711:10;;;:16;71751:4;71737:11;;;:18;71779:4;71765:11;;;:18;71807:4;71793:11;;;:18;71835:4;71821:11;;;:18;71863:4;71849:11;;;:18;71891:4;71877:11;;;:18;71919:4;71905:11;;;:18;71947:4;71933:11;;;:18;71975:4;71961:11;;;:18;72003:4;71989:11;;;:18;72031:4;72017:11;;;:18;72059:4;72045:11;;;:18;72087:4;72073:11;;;:18;72115:4;72101:11;;;:18;72143:4;72129:11;;;:18;72171:4;72157:11;;;:18;72199:4;72185:11;;;:18;72227:4;72213:11;;;:18;72255:4;72241:11;;;:18;72283:4;72269:11;;;:18;72311:4;72297:11;;;:18;72339:4;72325:11;;;:18;71477:7;71386:964::o;70490:589::-;70663:11;;;;70614:16;;;70685:388;69070:2;70705:1;:14;70685:388;;;70771:4;70756:11;;;70755:20;;;70793:12;;;70789:215;;70863:5;70876:1;70863:15;;;;;;;:::i;:::-;;;70846:43;;;;;;18270:19:1;;;;18305:12;;18298:28;;;18342:12;;70846:43:0;;;;;;;;;;;;70836:54;;;;;;70825:65;;70789:215;;;70967:8;70977:7;70985:1;70977:10;;;;;;;:::i;:::-;;;;;70950:38;;;;;;;;18270:19:1;;;18314:2;18305:12;;18298:28;18351:2;18342:12;;18113:247;70950:38:0;;;;;;;;;;;;;70940:49;;;;;;70929:60;;70789:215;-1:-1:-1;71045:3:0;;70685:388;;;;70636:443;70490:589;;;;:::o;55542:165::-;55675:23;;;55622:4;51209:19;;;:12;;;:19;;;;;;:24;;55645:55;51113:127;10135:578;10213:7;10237:26;10244:7;10253:9;10237:6;:26::i;:::-;10232:451;;10282:9;10295:35;10313:15;10320:7;14479:3;14475:17;;14268:268;10313:15;10305:24;;10295:9;:35::i;:::-;10279:51;;;10347:9;10360:29;10378:9;10370:18;;10360:9;:29::i;:::-;10447:186;;18732:31:1;10447:186:0;;;18720:44:1;18783:66;18887:3;18883:16;;;18879:25;;18865:12;;;18858:47;18935:15;18921:12;;;18914:37;18985:16;;;18981:25;18967:12;;;18960:47;10344:45:0;;-1:-1:-1;10403:17:0;;-1:-1:-1;19023:12:1;;10447:186:0;;;;;;;;;;;;10403:244;;10668:3;10661:11;;-1:-1:-1;;;10661:11:0;;;;;;;;:::i;10232:451::-;-1:-1:-1;10699:7:0;;10135:578;-1:-1:-1;10135:578:0:o;89076:153::-;89152:6;89136:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;89184:37:0::1;-1:-1:-1::0;;89184:15:0;::::1;87083:2;89218;89184:15;:37::i;:::-;89170:52;;::::0;89076:153;-1:-1:-1;;;89076:153:0:o;88880:147::-;88953:6;88937:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88985:34:0::1;-1:-1:-1::0;;88985:15:0;::::1;87030:2;89016;88985:15;:34::i;88685:149::-:0;88759:6;88743:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88791:35:0::1;-1:-1:-1::0;;88791:15:0;::::1;86980:2;88823;88791:15;:35::i;88489:149::-:0;88563:6;88547:5;87135:35;82150:10;82143:18;;87135:35;-1:-1:-1;88595:35:0::1;-1:-1:-1::0;;88595:15:0;::::1;86930:1;88627:2;88595:15;:35::i;69529:750::-:0;69614:11;;;;;;69133:1;;69117:13;;:1;:13;:::i;:::-;:17;;;;:::i;:::-;69643:4;:17;69635:46;;;;-1:-1:-1;;;69635:46:0;;20742:2:1;69635:46:0;;;20724:21:1;20781:2;20761:18;;;20754:30;20820:18;20800;;;20793:46;20856:18;;69635:46:0;20540:340:1;69635:46:0;69716:6;;69742:11;;;:18;;;69775:9;69770:319;69070:2;69790:1;:14;69770:319;;;69827:4;69834:1;69827:8;69840:1;69826:15;69822:101;;69879:5;69861;69874:1;69861:15;;;;;;;:::i;:::-;;:23;-1:-1:-1;;;;69529:750:0:o;69822:101::-;69971:5;69984:1;69971:15;;;;;;;:::i;:::-;;;69954:40;;;;;;18270:19:1;;;;18305:12;;18298:28;;;18342:12;;69954:40:0;;;;;;;;;;;;;69944:51;;69954:40;69944:51;;;;;-1:-1:-1;70018:1:0;70009:10;;;;70061:3;69770:319;;;-1:-1:-1;70259:13:0;;:::i;:::-;69589:690;69529:750;;:::o;12858:462::-;12969:15;;13011:11;13018:4;13011;:11;:::i;:::-;12996:26;;13137:4;13131:11;13125:4;13122:21;13119:66;;;-1:-1:-1;13170:1:0;13119:66;13208:4;13216:1;13208:9;13204:51;;-1:-1:-1;;13233:11:0;;;;;13204:51;-1:-1:-1;;12127:2:0;12123:27;;;12197:17;;;;12189:26;;;12261:17;12257:2;12253:26;;12858:462::o;17191:399::-;17330:7;17349:12;17364;17368:7;15448:3;15444:17;2732:26;15440:29;;15121:364;17364:12;17349:27;;;;17460:12;17464:7;17460:3;:12::i;:::-;17453:4;17437:13;17444:6;17437:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17433:77;;;-1:-1:-1;;17488:11:0;;;;;17433:77;17527:13;17534:6;17527:4;:13;:::i;:::-;17520:20;;17557:26;17563:7;17557:26;;17572:4;17578;17557:5;:26::i;:::-;17550:33;17191:399;-1:-1:-1;;;;;;17191:399:0:o;27098:902::-;27176:15;-1:-1:-1;;8034:15:0;;;;27203:69;;;;-1:-1:-1;;;27203:69:0;;21276:2:1;27203:69:0;;;21258:21:1;21315:2;21295:18;;;21288:30;21354:34;21334:18;;;21327:62;21425:10;21405:18;;;21398:38;21453:19;;27203:69:0;21074:404:1;27203:69:0;27290:16;27298:7;27290;:16::i;:::-;27282:72;;;;-1:-1:-1;;;27282:72:0;;21685:2:1;27282:72:0;;;21667:21:1;21724:2;21704:18;;;21697:30;21763:34;21743:18;;;21736:62;21834:13;21814:18;;;21807:41;21865:19;;27282:72:0;21483:407:1;27282:72:0;27364:12;27379;27383:7;16554:2;16550:16;2732:26;16546:28;;16308:282;27379:12;27364:27;;;;27401:15;27419:12;27423:7;15448:3;15444:17;2732:26;15440:29;;15121:364;27419:12;27401:30;;;;27442:11;27563:4;27557:11;27550:18;;27650:7;27645:3;27642:16;27639:94;;;27690:4;27684;27677:18;27639:94;27905:4;27896:7;27890:4;27881:7;27878:1;27871:5;27860:50;27856:55;27941:52;27962:15;27969:7;14479:3;14475:17;;14268:268;27962:15;12123:27;12127:2;12123:27;;;;12197:17;;12189:26;;12261:17;;12257:2;12253:26;;11873:446;22517:290;22573:14;22599:12;22614;22618:7;15448:3;15444:17;2732:26;15440:29;;15121:364;22614:12;22599:27;;;;22636:12;22651;22655:7;16554:2;16550:16;2732:26;16546:28;;16308:282;22651:12;22636:27;;22770:21;;;;22517:290;-1:-1:-1;;;22517:290:0:o;41468:227::-;41546:7;41566:17;41585:18;41607:27;41618:4;41624:9;41607:10;:27::i;:::-;41565:69;;;;41644:18;41656:5;41644:11;:18::i;:::-;-1:-1:-1;41679:9:0;41468:227;-1:-1:-1;;;41468:227:0:o;18823:741::-;18969:17;19001:9;19014:15;19024:4;19014:9;:15::i;:::-;18998:31;;;19042:9;19055:15;19065:4;19055:9;:15::i;:::-;19039:31;;;19083:9;19096:17;19106:6;19096:9;:17::i;:::-;19080:33;;;19126:9;19139:17;19149:6;19139:9;:17::i;:::-;19123:33;;;19306:1;19368;19448;19510;19192:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19166:391;;18988:576;;;;18823:741;;;;;;:::o;49072:404::-;49135:4;51209:19;;;:12;;;:19;;;;;;49151:319;;-1:-1:-1;49193:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;49373:18;;49351:19;;;:12;;;:19;;;;;;:40;;;;49405:11;;49151:319;-1:-1:-1;49454:5:0;49447:12;;9705:132;9779:4;9821:9;9802:28;;:15;9809:7;14479:3;14475:17;;14268:268;9802:15;:28;;;;9705:132;-1:-1:-1;;;9705:132:0:o;5093:667::-;5147:13;;5203:2;5188:258;5211:2;5207:1;:6;;;5188:258;;;5231:11;5258:5;:1;5262;5258:5;:::i;:::-;5251:13;;:2;:13;;5231:34;;5288:14;5296:5;5288:7;:14::i;:::-;5279:23;;;;;;5320:1;:7;;5325:2;5320:7;5316:58;;5357:2;5347:12;;;;;5316:58;-1:-1:-1;5415:6:0;;5188:258;;;-1:-1:-1;5509:2:0;5494:260;5517:3;5513:1;:7;;;5494:260;;;5538:11;5565:5;:1;5569;5565:5;:::i;:::-;5558:13;;:2;:13;;5538:34;;5596:14;5604:5;5596:7;:14::i;:::-;5586:24;;;;;;5628:1;:6;;5633:1;5628:6;5624:58;;5665:2;5654:13;;;;;5624:58;-1:-1:-1;5723:6:0;;5494:260;;;;5093:667;;;:::o;16764:147::-;16817:7;16882:12;16886:7;16554:2;16550:16;2732:26;16546:28;;16308:282;16882:12;16867;16871:7;15448:3;15444:17;2732:26;15440:29;;15121:364;16867:12;:27;16860:34;;;;16764:147;;;:::o;8707:333::-;8764:8;8788:15;8795:7;14479:3;14475:17;;14268:268;8788:15;:31;;8807:12;8788:31;8784:74;;-1:-1:-1;8842:5:0;;8707:333;-1:-1:-1;8707:333:0:o;8784:74::-;8867:12;8882;8886:7;8882:3;:12::i;:::-;9017:4;9011:11;-1:-1:-1;8998:26:0;;8707:333;-1:-1:-1;;;8707:333:0:o;39403:1279::-;39484:7;39493:12;39714:9;:16;39734:2;39714:22;39710:966;;40003:4;39988:20;;39982:27;40052:4;40037:20;;40031:27;40109:4;40094:20;;40088:27;39752:9;40080:36;40150:25;40161:4;40080:36;39982:27;40031;40150:10;:25::i;:::-;40143:32;;;;;;;;;39710:966;40196:9;:16;40216:2;40196:22;40192:484;;40465:4;40450:20;;40444:27;40515:4;40500:20;;40494:27;40555:23;40566:4;40444:27;40494;40555:10;:23::i;:::-;40548:30;;;;;;;;40192:484;-1:-1:-1;40625:1:0;;-1:-1:-1;40629:35:0;40192:484;39403:1279;;;;;:::o;37708:631::-;37785:20;37776:5;:29;;;;;;;;:::i;:::-;;37772:561;;37708:631;:::o;37772:561::-;37881:29;37872:5;:38;;;;;;;;:::i;:::-;;37868:465;;37926:34;;-1:-1:-1;;;37926:34:0;;23997:2:1;37926:34:0;;;23979:21:1;24036:2;24016:18;;;24009:30;24075:26;24055:18;;;24048:54;24119:18;;37926:34:0;23795:348:1;37868:465:0;37990:35;37981:5;:44;;;;;;;;:::i;:::-;;37977:356;;38041:41;;-1:-1:-1;;;38041:41:0;;24350:2:1;38041:41:0;;;24332:21:1;24389:2;24369:18;;;24362:30;24428:33;24408:18;;;24401:61;24479:18;;38041:41:0;24148:355:1;37977:356:0;38112:30;38103:5;:39;;;;;;;;:::i;:::-;;38099:234;;38158:44;;-1:-1:-1;;;38158:44:0;;24710:2:1;38158:44:0;;;24692:21:1;24749:2;24729:18;;;24722:30;24788:34;24768:18;;;24761:62;24859:4;24839:18;;;24832:32;24881:19;;38158:44:0;24508:398:1;38099:234:0;38232:30;38223:5;:39;;;;;;;;:::i;:::-;;38219:114;;38278:44;;-1:-1:-1;;;38278:44:0;;25113:2:1;38278:44:0;;;25095:21:1;25152:2;25132:18;;;25125:30;25191:34;25171:18;;;25164:62;25262:4;25242:18;;;25235:32;25284:19;;38278:44:0;24911:398:1;4570:199:0;4620:14;4657:18;4673:1;4667:2;:7;;;;4657:9;:18::i;:::-;4646:29;;4699:13;;;;;;4711:1;4699:13;4733;4743:2;4733:9;:13::i;:::-;4722:24;;;;4570:199;-1:-1:-1;4570:199:0:o;42876:1603::-;43002:7;;43926:66;43913:79;;43909:161;;;-1:-1:-1;44024:1:0;;-1:-1:-1;44028:30:0;44008:51;;43909:161;44083:1;:7;;44088:2;44083:7;;:18;;;;;44094:1;:7;;44099:2;44094:7;;44083:18;44079:100;;;-1:-1:-1;44133:1:0;;-1:-1:-1;44137:30:0;44117:51;;44079:100;44290:24;;;44273:14;44290:24;;;;;;;;;25541:25:1;;;25614:4;25602:17;;25582:18;;;25575:45;;;;25636:18;;;25629:34;;;25679:18;;;25672:34;;;44290:24:0;;25513:19:1;;44290:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44290:24:0;;;;;;-1:-1:-1;;44328:20:0;;;44324:101;;44380:1;44384:29;44364:50;;;;;;;44324:101;44443:6;-1:-1:-1;44451:20:0;;-1:-1:-1;42876:1603:0;;;;;;;;:::o;41949:336::-;42059:7;;42117:66;42104:80;;42059:7;42210:25;42226:3;42211:18;;;42233:2;42210:25;:::i;:::-;42194:42;;42253:25;42264:4;42270:1;42273;42276;42253:10;:25::i;:::-;42246:32;;;;;;41949:336;;;;;;:::o;3005:1393::-;3057:10;3223:4;3218:9;;;;3269:15;;;;;3265:57;;-1:-1:-1;3307:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3265:57::-;3340:7;:15;;3351:4;3340:15;3336:57;;-1:-1:-1;3378:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3336:57::-;3411:7;:15;;3422:4;3411:15;3407:57;;-1:-1:-1;3449:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3407:57::-;3482:7;:15;;3493:4;3482:15;3478:57;;-1:-1:-1;3520:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3478:57::-;3553:7;:15;;3564:4;3553:15;3549:57;;-1:-1:-1;3591:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3549:57::-;3624:7;:15;;3635:4;3624:15;3620:57;;-1:-1:-1;3662:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3620:57::-;3695:7;:15;;3706:4;3695:15;3691:57;;-1:-1:-1;3733:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3691:57::-;3766:7;:15;;3777:4;3766:15;3762:57;;-1:-1:-1;3804:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3762:57::-;3837:7;:15;;3848:4;3837:15;3833:57;;-1:-1:-1;3875:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3833:57::-;3908:7;:15;;3919:4;3908:15;3904:57;;-1:-1:-1;3946:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3904:57::-;3979:7;:15;;3990:4;3979:15;3975:57;;-1:-1:-1;4017:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;3975:57::-;4050:7;:15;;4061:4;4050:15;4046:57;;-1:-1:-1;4088:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4046:57::-;4121:7;:15;;4132:4;4121:15;4117:57;;-1:-1:-1;4159:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4117:57::-;4192:7;:15;;4203:4;4192:15;4188:57;;-1:-1:-1;4230:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4188:57::-;4263:7;:15;;4274:4;4263:15;4259:57;;-1:-1:-1;4301:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;4259:57::-;4334:7;:15;;4345:4;4334:15;4330:57;;-1:-1:-1;4372:4:0;;3005:1393;-1:-1:-1;;3005:1393:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:184:1:-;248:77;245:1;238:88;345:4;342:1;335:15;369:4;366:1;359:15;385:777;427:5;480:3;473:4;465:6;461:17;457:27;447:55;;498:1;495;488:12;447:55;534:6;521:20;560:18;597:2;593;590:10;587:36;;;603:18;;:::i;:::-;737:2;731:9;799:4;791:13;;642:66;787:22;;;811:2;783:31;779:40;767:53;;;835:18;;;855:22;;;832:46;829:72;;;881:18;;:::i;:::-;921:10;917:2;910:22;956:2;948:6;941:18;1002:3;995:4;990:2;982:6;978:15;974:26;971:35;968:55;;;1019:1;1016;1009:12;968:55;1083:2;1076:4;1068:6;1064:17;1057:4;1049:6;1045:17;1032:54;1130:1;1123:4;1118:2;1110:6;1106:15;1102:26;1095:37;1150:6;1141:15;;;;;;385:777;;;;:::o;1167:320::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;1344:9;1331:23;1377:18;1369:6;1366:30;1363:50;;;1409:1;1406;1399:12;1363:50;1432:49;1473:7;1464:6;1453:9;1449:22;1432:49;:::i;1952:180::-;2011:6;2064:2;2052:9;2043:7;2039:23;2035:32;2032:52;;;2080:1;2077;2070:12;2032:52;-1:-1:-1;2103:23:1;;1952:180;-1:-1:-1;1952:180:1:o;2747:154::-;2833:42;2826:5;2822:54;2815:5;2812:65;2802:93;;2891:1;2888;2881:12;2906:247;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3073:9;3060:23;3092:31;3117:5;3092:31;:::i;3158:681::-;3329:2;3381:21;;;3451:13;;3354:18;;;3473:22;;;3300:4;;3329:2;3552:15;;;;3526:2;3511:18;;;3300:4;3595:218;3609:6;3606:1;3603:13;3595:218;;;3674:13;;3689:42;3670:62;3658:75;;3788:15;;;;3753:12;;;;3631:1;3624:9;3595:218;;;-1:-1:-1;3830:3:1;;3158:681;-1:-1:-1;;;;;;3158:681:1:o;4376:184::-;4428:77;4425:1;4418:88;4525:4;4522:1;4515:15;4549:4;4546:1;4539:15;4565:396;4708:2;4693:18;;4741:1;4730:13;;4720:201;;4777:77;4774:1;4767:88;4878:4;4875:1;4868:15;4906:4;4903:1;4896:15;4720:201;4930:25;;;4565:396;:::o;5498:163::-;5565:20;;5625:10;5614:22;;5604:33;;5594:61;;5651:1;5648;5641:12;5666:256;5732:6;5740;5793:2;5781:9;5772:7;5768:23;5764:32;5761:52;;;5809:1;5806;5799:12;5761:52;5832:28;5850:9;5832:28;:::i;:::-;5822:38;;5879:37;5912:2;5901:9;5897:18;5879:37;:::i;:::-;5869:47;;5666:256;;;;;:::o;6132:753::-;6243:6;6251;6259;6267;6275;6328:3;6316:9;6307:7;6303:23;6299:33;6296:53;;;6345:1;6342;6335:12;6296:53;6368:28;6386:9;6368:28;:::i;:::-;6358:38;;6443:2;6432:9;6428:18;6415:32;6405:42;;6466:37;6499:2;6488:9;6484:18;6466:37;:::i;:::-;6456:47;;6554:2;6543:9;6539:18;6526:32;6577:18;6618:2;6610:6;6607:14;6604:34;;;6634:1;6631;6624:12;6604:34;6657:49;6698:7;6689:6;6678:9;6674:22;6657:49;:::i;:::-;6647:59;;6759:3;6748:9;6744:19;6731:33;6715:49;;6789:2;6779:8;6776:16;6773:36;;;6805:1;6802;6795:12;6773:36;;6828:51;6871:7;6860:8;6849:9;6845:24;6828:51;:::i;:::-;6818:61;;;6132:753;;;;;;;;:::o;7420:184::-;7472:77;7469:1;7462:88;7569:4;7566:1;7559:15;7593:4;7590:1;7583:15;7609:258;7681:1;7691:113;7705:6;7702:1;7699:13;7691:113;;;7781:11;;;7775:18;7762:11;;;7755:39;7727:2;7720:10;7691:113;;;7822:6;7819:1;7816:13;7813:48;;;7857:1;7848:6;7843:3;7839:16;7832:27;7813:48;;7609:258;;;:::o;7872:316::-;7913:3;7951:5;7945:12;7978:6;7973:3;7966:19;7994:63;8050:6;8043:4;8038:3;8034:14;8027:4;8020:5;8016:16;7994:63;:::i;:::-;8102:2;8090:15;8107:66;8086:88;8077:98;;;;8177:4;8073:109;;7872:316;-1:-1:-1;;7872:316:1:o;8193:337::-;8380:42;8372:6;8368:55;8357:9;8350:74;8460:2;8455;8444:9;8440:18;8433:30;8331:4;8480:44;8520:2;8509:9;8505:18;8497:6;8480:44;:::i;8535:184::-;8587:77;8584:1;8577:88;8684:4;8681:1;8674:15;8708:4;8705:1;8698:15;8724:125;8764:4;8792:1;8789;8786:8;8783:34;;;8797:18;;:::i;:::-;-1:-1:-1;8834:9:1;;8724:125::o;9559:251::-;9629:6;9682:2;9670:9;9661:7;9657:23;9653:32;9650:52;;;9698:1;9695;9688:12;9650:52;9730:9;9724:16;9749:31;9774:5;9749:31;:::i;11095:228::-;11134:3;11162:10;11199:2;11196:1;11192:10;11229:2;11226:1;11222:10;11260:3;11256:2;11252:12;11247:3;11244:21;11241:47;;;11268:18;;:::i;:::-;11304:13;;11095:228;-1:-1:-1;;;;11095:228:1:o;11328:377::-;11521:2;11510:9;11503:21;11484:4;11547:44;11587:2;11576:9;11572:18;11564:6;11547:44;:::i;:::-;11639:9;11631:6;11627:22;11622:2;11611:9;11607:18;11600:50;11667:32;11692:6;11684;11667:32;:::i;14521:244::-;14560:3;14588:26;14641:2;14638:1;14634:10;14671:2;14668:1;14664:10;14702:3;14698:2;14694:12;14689:3;14686:21;14683:47;;;14710:18;;:::i;15579:238::-;15617:7;15657:4;15654:1;15650:12;15689:4;15686:1;15682:12;15749:3;15743:4;15739:14;15734:3;15731:23;15724:3;15717:11;15710:19;15706:49;15703:75;;;15758:18;;:::i;:::-;15798:13;;15579:238;-1:-1:-1;;;15579:238:1:o;15822:224::-;15861:3;15889:6;15922:2;15919:1;15915:10;15952:2;15949:1;15945:10;15983:3;15979:2;15975:12;15970:3;15967:21;15964:47;;;15991:18;;:::i;16051:1073::-;16376:3;16404:66;16513:2;16504:6;16499:3;16495:16;16491:25;16486:3;16479:38;16568:2;16559:6;16554:3;16550:16;16546:25;16542:1;16537:3;16533:11;16526:46;16623:2;16614:6;16609:3;16605:16;16601:25;16597:1;16592:3;16588:11;16581:46;16678:2;16669:6;16664:3;16660:16;16656:25;16652:1;16647:3;16643:11;16636:46;;16711:6;16705:13;16727:61;16781:6;16777:1;16772:3;16768:11;16761:4;16753:6;16749:17;16727:61;:::i;:::-;16848:13;;16807:16;;;;16870:62;16848:13;16919:1;16911:10;;16904:4;16892:17;;16870:62;:::i;:::-;16993:13;;16951:17;;;17015:62;16993:13;17064:1;17056:10;;17049:4;17037:17;;17015:62;:::i;:::-;17097:17;17116:1;17093:25;;16051:1073;-1:-1:-1;;;;;;;;;16051:1073:1:o;17129:195::-;17167:4;17204;17201:1;17197:12;17236:4;17233:1;17229:12;17261:3;17256;17253:12;17250:38;;;17268:18;;:::i;:::-;17305:13;;;17129:195;-1:-1:-1;;;17129:195:1:o;17329:128::-;17369:3;17400:1;17396:6;17393:1;17390:13;17387:39;;;17406:18;;:::i;:::-;-1:-1:-1;17442:9:1;;17329:128::o;17462:219::-;17611:2;17600:9;17593:21;17574:4;17631:44;17671:2;17660:9;17656:18;17648:6;17631:44;:::i;19046:482::-;19135:1;19178:5;19135:1;19192:330;19213:7;19203:8;19200:21;19192:330;;;19332:4;19264:66;19260:77;19254:4;19251:87;19248:113;;;19341:18;;:::i;:::-;19391:7;19381:8;19377:22;19374:55;;;19411:16;;;;19374:55;19490:22;;;;19450:15;;;;19192:330;;;19196:3;19046:482;;;;;:::o;19533:866::-;19582:5;19612:8;19602:80;;-1:-1:-1;19653:1:1;19667:5;;19602:80;19701:4;19691:76;;-1:-1:-1;19738:1:1;19752:5;;19691:76;19783:4;19801:1;19796:59;;;;19869:1;19864:130;;;;19776:218;;19796:59;19826:1;19817:10;;19840:5;;;19864:130;19901:3;19891:8;19888:17;19885:43;;;19908:18;;:::i;:::-;-1:-1:-1;;19964:1:1;19950:16;;19979:5;;19776:218;;20078:2;20068:8;20065:16;20059:3;20053:4;20050:13;20046:36;20040:2;20030:8;20027:16;20022:2;20016:4;20013:12;20009:35;20006:77;20003:159;;;-1:-1:-1;20115:19:1;;;20147:5;;20003:159;20194:34;20219:8;20213:4;20194:34;:::i;:::-;20324:6;20256:66;20252:79;20243:7;20240:92;20237:118;;;20335:18;;:::i;20404:131::-;20464:5;20493:36;20520:8;20514:4;20493:36;:::i;20885:184::-;20937:77;20934:1;20927:88;21034:4;21031:1;21024:15;21058:4;21055:1;21048:15;22399:1391;23121:34;23109:47;;23186:23;23181:2;23172:12;;23165:45;23229:66;23333:3;23329:16;;;23325:25;;23320:2;23311:12;;23304:47;23370:17;23412:2;23403:12;;23396:24;;;23454:16;;;23450:25;;23445:2;23436:12;;23429:47;23506:34;23501:2;23492:12;;23485:56;23572:3;23566;23557:13;;23550:26;23611:16;;;23607:25;;23601:3;23592:13;;23585:48;23658:3;23649:13;;23642:25;23702:16;;;23698:25;23692:3;23683:13;;23676:48;22357:3;23779;23770:13;;22345:16;-1:-1:-1;22377:11:1;;;23740:44;22280:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"leafIndex","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"destinationAndNonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"tips","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Dispatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"ImproperAttestation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updaterManager","type":"address"}],"name":"NewUpdaterManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"address","name":"reporter","type":"address"}],"name":"UpdaterSlashed","type":"event"},{"inputs":[],"name":"MAX_MESSAGE_BODY_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allNotaries","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destination","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"}],"name":"destinationAndNonce","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipientAddress","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNotary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"improperAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUpdaterManager","name":"_updaterManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_notary","type":"address"}],"name":"isNotary","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notariesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sensitiveValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_notary","type":"address"}],"name":"setFailed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newValue","type":"uint256"}],"name":"setSensitiveValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterManager","type":"address"}],"name":"setUpdaterManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Home.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"suggestUpdate","outputs":[{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updaterManager","outputs":[{"internalType":"contract IUpdaterManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"notice":"Emitted when a new message is dispatched via Nomad"},"ImproperAttestation(address,bytes)":{"notice":"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state"},"NewUpdaterManager(address)":{"notice":"Emitted when the UpdaterManager contract is changed"},"UpdaterSlashed(address,address)":{"notice":"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)"}},"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"notice":"Dispatch the message to the destination domain \u0026 recipient"},"improperAttestation(bytes)":{"notice":"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation."},"root()":{"notice":"Calculates and returns tree's current root"},"setUpdater(address)":{"notice":"Set a new Updater"},"setUpdaterManager(address)":{"notice":"Set a new UpdaterManager contract"},"suggestUpdate()":{"notice":"Suggest an update for the Updater to sign and submit."}},"version":1},"developerDoc":{"kind":"dev","methods":{"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"details":"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.","params":{"_destinationDomain":"Domain of destination chain","_messageBody":"Raw bytes content of message","_recipientAddress":"Address of recipient on destination chain as bytes32"}},"improperAttestation(bytes)":{"details":"Reverts (and doesn't slash updater) if signature is invalid or update not current","params":{"_attestation":"Attestation data and signature"},"returns":{"_0":"TRUE if update was an Improper Attestation (implying Updater was slashed)"}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setUpdater(address)":{"details":"To be set when rotating Updater after Fraud","params":{"_updater":"the new Updater"}},"setUpdaterManager(address)":{"details":"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation","params":{"_updaterManager":"the new UpdaterManager contract"}},"suggestUpdate()":{"details":"If no messages have been sent, null bytes returned for both","returns":{"_nonce":"Current nonce","_root":"Current merkle root"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destination\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"}],\"name\":\"destinationAndNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"isNotary\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sensitiveValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"setFailed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newValue\",\"type\":\"uint256\"}],\"name\":\"setSensitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum Home.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"details\":\"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.\",\"params\":{\"_destinationDomain\":\"Domain of destination chain\",\"_messageBody\":\"Raw bytes content of message\",\"_recipientAddress\":\"Address of recipient on destination chain as bytes32\"}},\"improperAttestation(bytes)\":{\"details\":\"Reverts (and doesn't slash updater) if signature is invalid or update not current\",\"params\":{\"_attestation\":\"Attestation data and signature\"},\"returns\":{\"_0\":\"TRUE if update was an Improper Attestation (implying Updater was slashed)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setUpdater(address)\":{\"details\":\"To be set when rotating Updater after Fraud\",\"params\":{\"_updater\":\"the new Updater\"}},\"setUpdaterManager(address)\":{\"details\":\"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\",\"params\":{\"_updaterManager\":\"the new UpdaterManager contract\"}},\"suggestUpdate()\":{\"details\":\"If no messages have been sent, null bytes returned for both\",\"returns\":{\"_nonce\":\"Current nonce\",\"_root\":\"Current merkle root\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"notice\":\"Emitted when a new message is dispatched via Nomad\"},\"ImproperAttestation(address,bytes)\":{\"notice\":\"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state\"},\"NewUpdaterManager(address)\":{\"notice\":\"Emitted when the UpdaterManager contract is changed\"},\"UpdaterSlashed(address,address)\":{\"notice\":\"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)\"}},\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Dispatch the message to the destination domain \u0026 recipient\"},\"improperAttestation(bytes)\":{\"notice\":\"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation.\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"},\"setUpdater(address)\":{\"notice\":\"Set a new Updater\"},\"setUpdaterManager(address)\":{\"notice\":\"Set a new UpdaterManager contract\"},\"suggestUpdate()\":{\"notice\":\"Suggest an update for the Updater to sign and submit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"HomeHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"MAX_MESSAGE_BODY_BYTES()":"522ae002","VERSION()":"ffa1ad74","allGuards()":"9fe03fa2","allNotaries()":"9817e315","count()":"06661abd","destinationAndNonce(uint32,uint32)":"da180e70","dispatch(uint32,bytes32,uint32,bytes,bytes)":"f7560e40","getGuard(uint256)":"629ddf69","getNotary(uint256)":"c07dc7f5","guardsAmount()":"246c2449","historicalRoots(uint256)":"7ea97f40","improperAttestation(bytes)":"0afe7f90","initialize(address)":"c4d66de8","isNotary(address)":"f13eed97","localDomain()":"8d3638f4","nonce()":"affed0e0","notariesAmount()":"8e62e9ef","owner()":"8da5cb5b","renounceOwnership()":"715018a6","root()":"ebf0c717","sensitiveValue()":"089d2894","setFailed(address)":"a1191a51","setSensitiveValue(uint256)":"48639d24","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","setUpdaterManager(address)":"9776120e","state()":"c19d93fb","suggestUpdate()":"36e104de","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","tree()":"fd54b228","updaterManager()":"9df6c8e1"}},"solidity/HomeHarness.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/HomeHarness.sol:IUpdaterManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"address payable","name":"_reporter","type":"address"}],"name":"slashUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"IUpdaterManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"slashUpdater(address)":"5b3c2cbf","updater()":"df034cd0"}},"solidity/HomeHarness.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"custom:oz-upgrades-unsafe-allow":"constructor constructor() { _disableInitializers(); } ``` ====","details":"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\"MyToken\", \"MTK\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\"MyToken\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```","events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor constructor() { _disableInitializers(); } ``` ====\",\"details\":\"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\\\"MyToken\\\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206d5609d71b06c43aa16a5b9f4ccdd35581ddf50e9c8fba3a1397bee8c344599864736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206d5609d71b06c43aa16a5b9f4ccdd35581ddf50e9c8fba3a1397bee8c344599864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"69007:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;69007:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"69007:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:MerkleTreeManager":{"code":"0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220dd786f68e4fb682c8db40afa31676fada6a06dcdaf6c67cd8e7b6a24d919bbce64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220dd786f68e4fb682c8db40afa31676fada6a06dcdaf6c67cd8e7b6a24d919bbce64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"116124:968:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"116124:968:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116729:81;116793:10;;116729:81;;;160:25:1;;;148:2;133:18;116729:81:0;;;;;;;116273:32;;;;;;:::i;:::-;;:::i;116545:81::-;;;:::i;116241:26::-;;;;;;;116273:32;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116273:32:0;:::o;116545:81::-;116582:7;116608:11;:4;:9;:11::i;:::-;116601:18;;116545:81;:::o;71146:122::-;71203:7;71229:32;71241:5;71248:12;:10;:12::i;:::-;71229:11;:32::i;:::-;71222:39;71146:122;-1:-1:-1;;71146:122:0:o;71386:964::-;71431:34;;:::i;:::-;71490:3;71477:16;;71516:3;71477:10;71503;;:16;71542:3;71529:10;;;:16;71568:3;71555:10;;;:16;71594:3;71581:10;;;:16;71620:3;71607:10;;;:16;71646:3;71633:10;;;:16;71672:3;71659:10;;;:16;71698:3;71685:10;;;:16;71724:3;71711:10;;;:16;71751:4;71737:11;;;:18;71779:4;71765:11;;;:18;71807:4;71793:11;;;:18;71835:4;71821:11;;;:18;71863:4;71849:11;;;:18;71891:4;71877:11;;;:18;71919:4;71905:11;;;:18;71947:4;71933:11;;;:18;71975:4;71961:11;;;:18;72003:4;71989:11;;;:18;72031:4;72017:11;;;:18;72059:4;72045:11;;;:18;72087:4;72073:11;;;:18;72115:4;72101:11;;;:18;72143:4;72129:11;;;:18;72171:4;72157:11;;;:18;72199:4;72185:11;;;:18;72227:4;72213:11;;;:18;72255:4;72241:11;;;:18;72283:4;72269:11;;;:18;72311:4;72297:11;;;:18;72339:4;72325:11;;;:18;71477:7;71386:964::o;70490:589::-;70663:11;;;;70614:16;;;70685:388;69070:2;70705:1;:14;70685:388;;;70771:4;70756:11;;;70755:20;;;70793:12;;;70789:215;;70863:5;70876:1;70863:15;;;;;;;:::i;:::-;;;70846:43;;;;;;909:19:1;;;;944:12;;937:28;;;981:12;;70846:43:0;;;;;;;;;;;;70836:54;;;;;;70825:65;;70789:215;;;70967:8;70977:7;70985:1;70977:10;;;;;;;:::i;:::-;;;;;70950:38;;;;;;;;909:19:1;;;953:2;944:12;;937:28;990:2;981:12;;752:247;70950:38:0;;;;;;;;;;;;;70940:49;;;;;;70929:60;;70789:215;-1:-1:-1;71045:3:0;;70685:388;;;;70636:443;70490:589;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;563:184::-;615:77;612:1;605:88;712:4;709:1;702:15;736:4;733:1;726:15","abiDefinition":[{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"root()":{"notice":"Calculates and returns tree's current root"}},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"MerkleTreeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"count()":"06661abd","historicalRoots(uint256)":"7ea97f40","root()":"ebf0c717","tree()":"fd54b228"}},"solidity/HomeHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d68f867782174e52085ebd396db960afccb6427cc9b7ba9c885f7b4801f9835564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d68f867782174e52085ebd396db960afccb6427cc9b7ba9c885f7b4801f9835564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"81448:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;81448:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"81448:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/HomeHarness.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c2daf27698cda67f8942012ea1b6cb47cf6738686a1bfb7586689892aa93a6bc64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c2daf27698cda67f8942012ea1b6cb47cf6738686a1bfb7586689892aa93a6bc64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"35642:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;35642:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"35642:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:SystemContract":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"SystemContract\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b"}},"solidity/HomeHarness.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122080b95c0a0564447278f1ba8189c6635d1faab45a84ab1d3d8d8eab479497d47f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122080b95c0a0564447278f1ba8189c6635d1faab45a84ab1d3d8d8eab479497d47f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"89422:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;89422:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"89422:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122074a959b828fde41e1156b006f04e5949b364bf55e9b52b7f0a505b0b6ec1084464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122074a959b828fde41e1156b006f04e5949b364bf55e9b52b7f0a505b0b6ec1084464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"86421:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;86421:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"86421:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200ece21e0761541fc44028f3225a340af1d1814445da8301c2e67d7d05bd194b064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200ece21e0761541fc44028f3225a340af1d1814445da8301c2e67d7d05bd194b064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"77031:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;77031:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"77031:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{}},"solidity/HomeHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220c950e5227828b3b0abe565b02888b07c56b560dc60dee268c094224f6636a2ab64736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220c950e5227828b3b0abe565b02888b07c56b560dc60dee268c094224f6636a2ab64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"88:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;88:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"88:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2601:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2601:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/HomeHarness.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208f8ad3211e3115f9b258019af793e66290cedc1a3aded054194bdf54b63a012964736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208f8ad3211e3115f9b258019af793e66290cedc1a3aded054194bdf54b63a012964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \ncontract HomeHarness is Home {\n uint256 public sensitiveValue;\n\n constructor(uint32 _domain) Home(_domain) {}\n\n function isNotary(address _notary) public view returns (bool) {\n return _isNotary(localDomain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setFailed(address _notary) public {\n _fail(_notary);\n }\n\n function destinationAndNonce(uint32 _destination, uint32 _nonce) public pure returns (uint64) {\n return _destinationAndNonce(_destination, _nonce);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50:33;;82:1;50:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;50:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/HomeHarness.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/HomeHarness.sol\":{\"keccak256\":\"0x83fede8b131a4a7ffbf472597498085dbf42f8f099a830dbcaa2d86904563453\",\"urls\":[\"bzz-raw://7064b7d8fbaf4915b9a5e03f1591d4e045231eb2944cf6fb516ade9733e22ecc\",\"dweb:/ipfs/QmVbG1CsZ4LsoUWzKP8k8uuV3zTX9sTmxfxsjwQu61uiFU\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file diff --git a/core/contracts/test/messageharness/messageharness.abigen.go b/core/contracts/test/messageharness/messageharness.abigen.go index 84563e1917..c0ba2d05d3 100644 --- a/core/contracts/test/messageharness/messageharness.abigen.go +++ b/core/contracts/test/messageharness/messageharness.abigen.go @@ -31,7 +31,7 @@ var ( // HeaderMetaData contains all meta data concerning the Header contract. var HeaderMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c8edaddd1a73e02423359ded235b6369ad4b189b3082f964ab0af5f44ca5d88264736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122079285bd073ccdc689299532d711fd90f40c2f0c8d68ab95eb0317e06a7a5ca2064736f6c634300080d0033", } // HeaderABI is the input ABI used to generate the binding from. @@ -204,7 +204,7 @@ func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method str // MessageMetaData contains all meta data concerning the Message contract. var MessageMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220cf880a41369369c56329af38ab922b24e58c3510844966fc54314d843c59948764736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d372489e722a522548452efb606a042af02f9ebfa707cfcd9dbed3f510387eca64736f6c634300080d0033", } // MessageABI is the input ABI used to generate the binding from. @@ -393,7 +393,7 @@ var MessageHarnessMetaData = &bind.MetaData{ "6dc3c4f7": "sender(bytes)", "045c6c0b": "tips(bytes)", }, - Bin: "0x608060405234801561001057600080fd5b5061193e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806381d030ef1161008c578063c97c703a11610066578063c97c703a146101de578063cb3eb0e1146101f1578063d7a7a72c14610204578063f45387ba1461021757600080fd5b806381d030ef146101a5578063985a5c31146101b8578063c81aa9c8146101cb57600080fd5b806352617f3c116100c857806352617f3c14610161578063639c5570146101775780636dc3c4f71461017f5780637c1cfff91461019257600080fd5b8063045c6c0b146100ef57806346fad66e146101185780634e76500414610139575b600080fd5b6101026100fd366004611367565b61024f565b60405161010f9190611416565b60405180910390f35b61012b610126366004611442565b61027c565b60405190815260200161010f565b61014c610147366004611367565b61032b565b60405163ffffffff909116815260200161010f565b60015b60405161ffff909116815260200161010f565b610164610352565b61012b61018d366004611367565b610368565b61014c6101a0366004611367565b610384565b6101026101b3366004611518565b6103a0565b61012b6101c6366004611367565b610477565b61014c6101d9366004611367565b610493565b6101026101ec366004611367565b6104af565b61014c6101ff366004611367565b6104cb565b61012b610212366004611367565b6104e7565b61022a610225366004611367565b610500565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010f565b606061027661026b6102608461051c565b62ffffff191661052a565b62ffffff191661056a565b92915050565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e08b811b82166022840152602683018b905289811b8216604684015288811b8216604a840152604e830188905286901b16606e82015281518082036052018152607290910190915260009061031d8185856105bd565b9a9950505050505050505050565b600061027661034761033c8461051c565b62ffffff19166105db565b62ffffff1916610612565b60006103606004600261164f565b60ff16905090565b600061027661037961033c8461051c565b62ffffff191661063c565b600061027661039561033c8461051c565b62ffffff191661065d565b606060006103b08787878761067e565b905060006104588e8e8e8e8e8e604080517e01000000000000000000000000000000000000000000000000000000000000602082015260e097881b7fffffffff000000000000000000000000000000000000000000000000000000009081166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281516052818303018152607290910190915290565b9050610465818386610710565b9e9d5050505050505050505050505050565b600061027661048861033c8461051c565b62ffffff191661078a565b60006102766104a461033c8461051c565b62ffffff19166107ab565b606061027661026b6104c08461051c565b62ffffff19166107cc565b60006102766104dc61033c8461051c565b62ffffff191661080b565b60006102766104f58361051c565b62ffffff191661082c565b600061027661051161033c8461051c565b62ffffff1916610851565b600061027682610539610862565b60008161053f62ffffff198216610539610886565b506105618361054f8560026109aa565b61055a8660036109aa565b60026109dc565b91505b50919050565b60606000806105878460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506105ac84836020016109fb565b508181016020016040529052919050565b60006105ca848484610710565b8051906020012090505b9392505050565b6000816105f062ffffff198216610539610886565b50610561836106008560016109aa565b61060b8660026109aa565b60016109dc565b60008161062860015b62ffffff19831690610886565b5061056162ffffff19841660266004610bd4565b600081610649600161061b565b5061056162ffffff19841660066020610c04565b60008161066a600161061b565b5061056162ffffff198416604e6004610bd4565b6040517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a086811b8216602284015285811b8216602e84015284811b8216603a84015283901b16604682015260609060520160405160208183030381529060405290505b949350505050565b82516060906000906107246004600261164f565b60ff166107319190611678565b905060008451826107429190611678565b905060016107526004600261164f565b60ff168383898989604051602001610770979695949392919061169e565b604051602081830303815290604052925050509392505050565b600081610797600161061b565b5061056162ffffff198416602e6020610c04565b6000816107b8600161061b565b5061056162ffffff198416602a6004610bd4565b6000816107e162ffffff198216610539610886565b50610561836107f18560036109aa565b601886901c6bffffffffffffffffffffffff1660036109dc565b600081610818600161061b565b5061056162ffffff19841660026004610bd4565b60008161084162ffffff198216610539610886565b5061056162ffffff198416610df6565b600061027661085f8361078a565b90565b81516000906020840161087d64ffffffffff85168284610e53565b95945050505050565b60006108928383610e9a565b6109a35760006108b16108a58560d81c90565b64ffffffffff16610ebd565b91505060006108c68464ffffffffff16610ebd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60405180910390fd5b5090919050565b60006105d460028360048111156109c3576109c36115f1565b6109cd919061173c565b62ffffff198516906002610bd4565b600061087d846109ec8186611779565b62ffffff198816919085610fa7565b600062ffffff1980841603610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161099a565b610a9b83611021565b610b27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161099a565b6000610b418460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115610b905760206060fd5b8285848460045afa50610bca610ba68760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b6000610be1826020611790565b610bec90600861164f565b60ff16610bfa858585610c04565b901c949350505050565b60008160ff16600003610c19575060006105d4565b610c318460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c4c60ff8416856117b3565b1115610cde57610cab610c6d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c938660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661105e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60208260ff161115610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161099a565b600882026000610d908660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600080610e118360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610e3b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080610e6083856117b3565b9050604051811115610e70575060005b80600003610e855762ffffff199150506105d4565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16610eae8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115610f30576000610edc82600861164f565b60ff1685901c9050610eed816110cc565b61ffff16841793508160ff16601014610f0857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610ec3565b50600f5b60ff8160ff161015610fa1576000610f4d82600861164f565b60ff1685901c9050610f5e816110cc565b61ffff16831792508160ff16600014610f7957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610f34565b50915091565b600080610fc28660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050610fdb866110fe565b84610fe687846117b3565b610ff091906117b3565b11156110035762ffffff19915050610708565b61100d85826117b3565b9050610bca8364ffffffffff168286610e53565b600061102d8260d81c90565b64ffffffffff1664ffffffffff0361104757506000919050565b6000611052836110fe565b60405110199392505050565b6060600061106b86610ebd565b915050600061107986610ebd565b915050600061108786610ebd565b915050600061109586610ebd565b915050838383836040516020016110af94939291906117cb565b604051602081830303815290604052945050505050949350505050565b60006110de60048360ff16901c611146565b60ff1661ffff919091161760081b6110f582611146565b60ff1617919050565b60006111188260181c6bffffffffffffffffffffffff1690565b6111308360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600060f08083179060ff821690036111615750603092915050565b8060ff1660f1036111755750603192915050565b8060ff1660f2036111895750603292915050565b8060ff1660f30361119d5750603392915050565b8060ff1660f4036111b15750603492915050565b8060ff1660f5036111c55750603592915050565b8060ff1660f6036111d95750603692915050565b8060ff1660f7036111ed5750603792915050565b8060ff1660f8036112015750603892915050565b8060ff1660f9036112155750603992915050565b8060ff1660fa036112295750606192915050565b8060ff1660fb0361123d5750606292915050565b8060ff1660fc036112515750606392915050565b8060ff1660fd036112655750606492915050565b8060ff1660fe036112795750606592915050565b8060ff1660ff036105645750606692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126112cd57600080fd5b813567ffffffffffffffff808211156112e8576112e861128d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561132e5761132e61128d565b8160405283815286602085880101111561134757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561137957600080fd5b813567ffffffffffffffff81111561139057600080fd5b610708848285016112bc565b60005b838110156113b757818101518382015260200161139f565b838111156113c6576000848401525b50505050565b600081518084526113e481602086016020860161139c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105d460208301846113cc565b803563ffffffff8116811461143d57600080fd5b919050565b600080600080600080600080610100898b03121561145f57600080fd5b61146889611429565b97506020890135965061147d60408a01611429565b955061148b60608a01611429565b9450608089013593506114a060a08a01611429565b925060c089013567ffffffffffffffff808211156114bd57600080fd5b6114c98c838d016112bc565b935060e08b01359150808211156114df57600080fd5b506114ec8b828c016112bc565b9150509295985092959890939650565b80356bffffffffffffffffffffffff8116811461143d57600080fd5b60008060008060008060008060008060006101608c8e03121561153a57600080fd5b6115438c611429565b9a5060208c0135995061155860408d01611429565b985061156660608d01611429565b975060808c0135965061157b60a08d01611429565b955061158960c08d016114fc565b945061159760e08d016114fc565b93506115a66101008d016114fc565b92506115b56101208d016114fc565b91506101408c013567ffffffffffffffff8111156115d257600080fd5b6115de8e828f016112bc565b9150509295989b509295989b9093969950565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff84168160ff048111821515161561167057611670611620565b029392505050565b600061ffff80831681851680830382111561169557611695611620565b01949350505050565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516116fe81600885016020890161139c565b84519083019061171581600884016020890161139c565b845191019061172b81600884016020880161139c565b016008019998505050505050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561177457611774611620565b500290565b60008282101561178b5761178b611620565b500390565b600060ff821660ff8416808210156117aa576117aa611620565b90039392505050565b600082198211156117c6576117c6611620565b500190565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201610bca56fea26469706673582212200d433cf58b1c411e28dea26e6cfce55626c077761ae2aefdef024731ec7fd18464736f6c634300080d0033", + Bin: "0x608060405234801561001057600080fd5b5061193e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806381d030ef1161008c578063c97c703a11610066578063c97c703a146101de578063cb3eb0e1146101f1578063d7a7a72c14610204578063f45387ba1461021757600080fd5b806381d030ef146101a5578063985a5c31146101b8578063c81aa9c8146101cb57600080fd5b806352617f3c116100c857806352617f3c14610161578063639c5570146101775780636dc3c4f71461017f5780637c1cfff91461019257600080fd5b8063045c6c0b146100ef57806346fad66e146101185780634e76500414610139575b600080fd5b6101026100fd366004611367565b61024f565b60405161010f9190611416565b60405180910390f35b61012b610126366004611442565b61027c565b60405190815260200161010f565b61014c610147366004611367565b61032b565b60405163ffffffff909116815260200161010f565b60015b60405161ffff909116815260200161010f565b610164610352565b61012b61018d366004611367565b610368565b61014c6101a0366004611367565b610384565b6101026101b3366004611518565b6103a0565b61012b6101c6366004611367565b610477565b61014c6101d9366004611367565b610493565b6101026101ec366004611367565b6104af565b61014c6101ff366004611367565b6104cb565b61012b610212366004611367565b6104e7565b61022a610225366004611367565b610500565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010f565b606061027661026b6102608461051c565b62ffffff191661052a565b62ffffff191661056a565b92915050565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e08b811b82166022840152602683018b905289811b8216604684015288811b8216604a840152604e830188905286901b16606e82015281518082036052018152607290910190915260009061031d8185856105bd565b9a9950505050505050505050565b600061027661034761033c8461051c565b62ffffff19166105db565b62ffffff1916610612565b60006103606004600261164f565b60ff16905090565b600061027661037961033c8461051c565b62ffffff191661063c565b600061027661039561033c8461051c565b62ffffff191661065d565b606060006103b08787878761067e565b905060006104588e8e8e8e8e8e604080517e01000000000000000000000000000000000000000000000000000000000000602082015260e097881b7fffffffff000000000000000000000000000000000000000000000000000000009081166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281516052818303018152607290910190915290565b9050610465818386610710565b9e9d5050505050505050505050505050565b600061027661048861033c8461051c565b62ffffff191661078a565b60006102766104a461033c8461051c565b62ffffff19166107ab565b606061027661026b6104c08461051c565b62ffffff19166107cc565b60006102766104dc61033c8461051c565b62ffffff191661080b565b60006102766104f58361051c565b62ffffff191661082c565b600061027661051161033c8461051c565b62ffffff1916610851565b600061027682610539610862565b60008161053f62ffffff198216610539610886565b506105618361054f8560026109aa565b61055a8660036109aa565b60026109dc565b91505b50919050565b60606000806105878460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506105ac84836020016109fb565b508181016020016040529052919050565b60006105ca848484610710565b8051906020012090505b9392505050565b6000816105f062ffffff198216610539610886565b50610561836106008560016109aa565b61060b8660026109aa565b60016109dc565b60008161062860015b62ffffff19831690610886565b5061056162ffffff19841660266004610bd4565b600081610649600161061b565b5061056162ffffff19841660066020610c04565b60008161066a600161061b565b5061056162ffffff198416604e6004610bd4565b6040517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a086811b8216602284015285811b8216602e84015284811b8216603a84015283901b16604682015260609060520160405160208183030381529060405290505b949350505050565b82516060906000906107246004600261164f565b60ff166107319190611678565b905060008451826107429190611678565b905060016107526004600261164f565b60ff168383898989604051602001610770979695949392919061169e565b604051602081830303815290604052925050509392505050565b600081610797600161061b565b5061056162ffffff198416602e6020610c04565b6000816107b8600161061b565b5061056162ffffff198416602a6004610bd4565b6000816107e162ffffff198216610539610886565b50610561836107f18560036109aa565b601886901c6bffffffffffffffffffffffff1660036109dc565b600081610818600161061b565b5061056162ffffff19841660026004610bd4565b60008161084162ffffff198216610539610886565b5061056162ffffff198416610df6565b600061027661085f8361078a565b90565b81516000906020840161087d64ffffffffff85168284610e53565b95945050505050565b60006108928383610e9a565b6109a35760006108b16108a58560d81c90565b64ffffffffff16610ebd565b91505060006108c68464ffffffffff16610ebd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60405180910390fd5b5090919050565b60006105d460028360048111156109c3576109c36115f1565b6109cd919061173c565b62ffffff198516906002610bd4565b600061087d846109ec8186611779565b62ffffff198816919085610fa7565b600062ffffff1980841603610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161099a565b610a9b83611021565b610b27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161099a565b6000610b418460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115610b905760206060fd5b8285848460045afa50610bca610ba68760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b6000610be1826020611790565b610bec90600861164f565b60ff16610bfa858585610c04565b901c949350505050565b60008160ff16600003610c19575060006105d4565b610c318460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c4c60ff8416856117b3565b1115610cde57610cab610c6d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c938660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661105e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60208260ff161115610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161099a565b600882026000610d908660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600080610e118360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610e3b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080610e6083856117b3565b9050604051811115610e70575060005b80600003610e855762ffffff199150506105d4565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16610eae8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115610f30576000610edc82600861164f565b60ff1685901c9050610eed816110cc565b61ffff16841793508160ff16601014610f0857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610ec3565b50600f5b60ff8160ff161015610fa1576000610f4d82600861164f565b60ff1685901c9050610f5e816110cc565b61ffff16831792508160ff16600014610f7957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610f34565b50915091565b600080610fc28660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050610fdb866110fe565b84610fe687846117b3565b610ff091906117b3565b11156110035762ffffff19915050610708565b61100d85826117b3565b9050610bca8364ffffffffff168286610e53565b600061102d8260d81c90565b64ffffffffff1664ffffffffff0361104757506000919050565b6000611052836110fe565b60405110199392505050565b6060600061106b86610ebd565b915050600061107986610ebd565b915050600061108786610ebd565b915050600061109586610ebd565b915050838383836040516020016110af94939291906117cb565b604051602081830303815290604052945050505050949350505050565b60006110de60048360ff16901c611146565b60ff1661ffff919091161760081b6110f582611146565b60ff1617919050565b60006111188260181c6bffffffffffffffffffffffff1690565b6111308360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600060f08083179060ff821690036111615750603092915050565b8060ff1660f1036111755750603192915050565b8060ff1660f2036111895750603292915050565b8060ff1660f30361119d5750603392915050565b8060ff1660f4036111b15750603492915050565b8060ff1660f5036111c55750603592915050565b8060ff1660f6036111d95750603692915050565b8060ff1660f7036111ed5750603792915050565b8060ff1660f8036112015750603892915050565b8060ff1660f9036112155750603992915050565b8060ff1660fa036112295750606192915050565b8060ff1660fb0361123d5750606292915050565b8060ff1660fc036112515750606392915050565b8060ff1660fd036112655750606492915050565b8060ff1660fe036112795750606592915050565b8060ff1660ff036105645750606692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126112cd57600080fd5b813567ffffffffffffffff808211156112e8576112e861128d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561132e5761132e61128d565b8160405283815286602085880101111561134757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561137957600080fd5b813567ffffffffffffffff81111561139057600080fd5b610708848285016112bc565b60005b838110156113b757818101518382015260200161139f565b838111156113c6576000848401525b50505050565b600081518084526113e481602086016020860161139c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105d460208301846113cc565b803563ffffffff8116811461143d57600080fd5b919050565b600080600080600080600080610100898b03121561145f57600080fd5b61146889611429565b97506020890135965061147d60408a01611429565b955061148b60608a01611429565b9450608089013593506114a060a08a01611429565b925060c089013567ffffffffffffffff808211156114bd57600080fd5b6114c98c838d016112bc565b935060e08b01359150808211156114df57600080fd5b506114ec8b828c016112bc565b9150509295985092959890939650565b80356bffffffffffffffffffffffff8116811461143d57600080fd5b60008060008060008060008060008060006101608c8e03121561153a57600080fd5b6115438c611429565b9a5060208c0135995061155860408d01611429565b985061156660608d01611429565b975060808c0135965061157b60a08d01611429565b955061158960c08d016114fc565b945061159760e08d016114fc565b93506115a66101008d016114fc565b92506115b56101208d016114fc565b91506101408c013567ffffffffffffffff8111156115d257600080fd5b6115de8e828f016112bc565b9150509295989b509295989b9093969950565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff84168160ff048111821515161561167057611670611620565b029392505050565b600061ffff80831681851680830382111561169557611695611620565b01949350505050565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516116fe81600885016020890161139c565b84519083019061171581600884016020890161139c565b845191019061172b81600884016020880161139c565b016008019998505050505050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561177457611774611620565b500290565b60008282101561178b5761178b611620565b500390565b600060ff821660ff8416808210156117aa576117aa611620565b90039392505050565b600082198211156117c6576117c6611620565b500190565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201610bca56fea264697066735822122089be01887807d993be55d0deeea3e8d1eebb905286f817fbd90e73a773d2b05964736f6c634300080d0033", } // MessageHarnessABI is the input ABI used to generate the binding from. @@ -1004,7 +1004,7 @@ func (_MessageHarness *MessageHarnessCallerSession) Tips(_message []byte) ([]byt // TipsMetaData contains all meta data concerning the Tips contract. var TipsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b0756d9546e7b2b4430f26d5c0341e164889948353dd82e994099eb78e3d3c6f64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f3469144348bb87fd91eb6075375c413450f79177a79df3df4f532c0d2d9814364736f6c634300080d0033", } // TipsABI is the input ABI used to generate the binding from. @@ -1177,7 +1177,7 @@ func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, // TypeCastsMetaData contains all meta data concerning the TypeCasts contract. var TypeCastsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c35e25f0946b278c613f5ebbafe60a8a7c609ce7200241743e59bf36c324e16f64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122069b7b1b9a024871cfa8ccbdcfa6d301f5e627bc40a3d10b688ca869fe49b1e4164736f6c634300080d0033", } // TypeCastsABI is the input ABI used to generate the binding from. @@ -1353,7 +1353,7 @@ var TypedMemViewMetaData = &bind.MetaData{ Sigs: map[string]string{ "f26be3fc": "NULL()", }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220c22f1018f82777d7b0a5e7495d6d8c35c5962e2ace30e17414b6ee6723f7aaad64736f6c634300080d0033", + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122065d18d890d97379832d683ea0feb3baaba8ee9eab100fd3c386e477863365a6a64736f6c634300080d0033", } // TypedMemViewABI is the input ABI used to generate the binding from. diff --git a/core/contracts/test/messageharness/messageharness.contractinfo.json b/core/contracts/test/messageharness/messageharness.contractinfo.json index a1d53d90a4..eb6dc95d16 100644 --- a/core/contracts/test/messageharness/messageharness.contractinfo.json +++ b/core/contracts/test/messageharness/messageharness.contractinfo.json @@ -1 +1 @@ -{"solidity/MessageHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c8edaddd1a73e02423359ded235b6369ad4b189b3082f964ab0af5f44ca5d88264736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c8edaddd1a73e02423359ded235b6369ad4b189b3082f964ab0af5f44ca5d88264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(\n _updaterTip,\n _relayerTip,\n _proverTip,\n _processorTip\n );\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"38359:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;38359:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"38359:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0xd56bf4956dacf8171f3ad4aeb3a5b7d8caa7cbe9e8b69dfc8d9bd876eebd9a72\",\"urls\":[\"bzz-raw://ddfeebc4974db727553a7ca169c2faa33d43beeb304939917f1452adf389c71b\",\"dweb:/ipfs/QmS8RKA433rvBfZwRkF8JkTHbQi5X7a4ArQQo3wcwaTeuj\"]}},\"version\":1}"},"hashes":{}},"solidity/MessageHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220cf880a41369369c56329af38ab922b24e58c3510844966fc54314d843c59948764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220cf880a41369369c56329af38ab922b24e58c3510844966fc54314d843c59948764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(\n _updaterTip,\n _relayerTip,\n _proverTip,\n _processorTip\n );\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33386:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33386:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33386:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0xd56bf4956dacf8171f3ad4aeb3a5b7d8caa7cbe9e8b69dfc8d9bd876eebd9a72\",\"urls\":[\"bzz-raw://ddfeebc4974db727553a7ca169c2faa33d43beeb304939917f1452adf389c71b\",\"dweb:/ipfs/QmS8RKA433rvBfZwRkF8JkTHbQi5X7a4ArQQo3wcwaTeuj\"]}},\"version\":1}"},"hashes":{}},"solidity/MessageHarness.sol:MessageHarness":{"code":"0x608060405234801561001057600080fd5b5061193e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806381d030ef1161008c578063c97c703a11610066578063c97c703a146101de578063cb3eb0e1146101f1578063d7a7a72c14610204578063f45387ba1461021757600080fd5b806381d030ef146101a5578063985a5c31146101b8578063c81aa9c8146101cb57600080fd5b806352617f3c116100c857806352617f3c14610161578063639c5570146101775780636dc3c4f71461017f5780637c1cfff91461019257600080fd5b8063045c6c0b146100ef57806346fad66e146101185780634e76500414610139575b600080fd5b6101026100fd366004611367565b61024f565b60405161010f9190611416565b60405180910390f35b61012b610126366004611442565b61027c565b60405190815260200161010f565b61014c610147366004611367565b61032b565b60405163ffffffff909116815260200161010f565b60015b60405161ffff909116815260200161010f565b610164610352565b61012b61018d366004611367565b610368565b61014c6101a0366004611367565b610384565b6101026101b3366004611518565b6103a0565b61012b6101c6366004611367565b610477565b61014c6101d9366004611367565b610493565b6101026101ec366004611367565b6104af565b61014c6101ff366004611367565b6104cb565b61012b610212366004611367565b6104e7565b61022a610225366004611367565b610500565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010f565b606061027661026b6102608461051c565b62ffffff191661052a565b62ffffff191661056a565b92915050565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e08b811b82166022840152602683018b905289811b8216604684015288811b8216604a840152604e830188905286901b16606e82015281518082036052018152607290910190915260009061031d8185856105bd565b9a9950505050505050505050565b600061027661034761033c8461051c565b62ffffff19166105db565b62ffffff1916610612565b60006103606004600261164f565b60ff16905090565b600061027661037961033c8461051c565b62ffffff191661063c565b600061027661039561033c8461051c565b62ffffff191661065d565b606060006103b08787878761067e565b905060006104588e8e8e8e8e8e604080517e01000000000000000000000000000000000000000000000000000000000000602082015260e097881b7fffffffff000000000000000000000000000000000000000000000000000000009081166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281516052818303018152607290910190915290565b9050610465818386610710565b9e9d5050505050505050505050505050565b600061027661048861033c8461051c565b62ffffff191661078a565b60006102766104a461033c8461051c565b62ffffff19166107ab565b606061027661026b6104c08461051c565b62ffffff19166107cc565b60006102766104dc61033c8461051c565b62ffffff191661080b565b60006102766104f58361051c565b62ffffff191661082c565b600061027661051161033c8461051c565b62ffffff1916610851565b600061027682610539610862565b60008161053f62ffffff198216610539610886565b506105618361054f8560026109aa565b61055a8660036109aa565b60026109dc565b91505b50919050565b60606000806105878460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506105ac84836020016109fb565b508181016020016040529052919050565b60006105ca848484610710565b8051906020012090505b9392505050565b6000816105f062ffffff198216610539610886565b50610561836106008560016109aa565b61060b8660026109aa565b60016109dc565b60008161062860015b62ffffff19831690610886565b5061056162ffffff19841660266004610bd4565b600081610649600161061b565b5061056162ffffff19841660066020610c04565b60008161066a600161061b565b5061056162ffffff198416604e6004610bd4565b6040517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a086811b8216602284015285811b8216602e84015284811b8216603a84015283901b16604682015260609060520160405160208183030381529060405290505b949350505050565b82516060906000906107246004600261164f565b60ff166107319190611678565b905060008451826107429190611678565b905060016107526004600261164f565b60ff168383898989604051602001610770979695949392919061169e565b604051602081830303815290604052925050509392505050565b600081610797600161061b565b5061056162ffffff198416602e6020610c04565b6000816107b8600161061b565b5061056162ffffff198416602a6004610bd4565b6000816107e162ffffff198216610539610886565b50610561836107f18560036109aa565b601886901c6bffffffffffffffffffffffff1660036109dc565b600081610818600161061b565b5061056162ffffff19841660026004610bd4565b60008161084162ffffff198216610539610886565b5061056162ffffff198416610df6565b600061027661085f8361078a565b90565b81516000906020840161087d64ffffffffff85168284610e53565b95945050505050565b60006108928383610e9a565b6109a35760006108b16108a58560d81c90565b64ffffffffff16610ebd565b91505060006108c68464ffffffffff16610ebd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60405180910390fd5b5090919050565b60006105d460028360048111156109c3576109c36115f1565b6109cd919061173c565b62ffffff198516906002610bd4565b600061087d846109ec8186611779565b62ffffff198816919085610fa7565b600062ffffff1980841603610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161099a565b610a9b83611021565b610b27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161099a565b6000610b418460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115610b905760206060fd5b8285848460045afa50610bca610ba68760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b6000610be1826020611790565b610bec90600861164f565b60ff16610bfa858585610c04565b901c949350505050565b60008160ff16600003610c19575060006105d4565b610c318460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c4c60ff8416856117b3565b1115610cde57610cab610c6d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c938660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661105e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60208260ff161115610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161099a565b600882026000610d908660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600080610e118360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610e3b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080610e6083856117b3565b9050604051811115610e70575060005b80600003610e855762ffffff199150506105d4565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16610eae8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115610f30576000610edc82600861164f565b60ff1685901c9050610eed816110cc565b61ffff16841793508160ff16601014610f0857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610ec3565b50600f5b60ff8160ff161015610fa1576000610f4d82600861164f565b60ff1685901c9050610f5e816110cc565b61ffff16831792508160ff16600014610f7957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610f34565b50915091565b600080610fc28660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050610fdb866110fe565b84610fe687846117b3565b610ff091906117b3565b11156110035762ffffff19915050610708565b61100d85826117b3565b9050610bca8364ffffffffff168286610e53565b600061102d8260d81c90565b64ffffffffff1664ffffffffff0361104757506000919050565b6000611052836110fe565b60405110199392505050565b6060600061106b86610ebd565b915050600061107986610ebd565b915050600061108786610ebd565b915050600061109586610ebd565b915050838383836040516020016110af94939291906117cb565b604051602081830303815290604052945050505050949350505050565b60006110de60048360ff16901c611146565b60ff1661ffff919091161760081b6110f582611146565b60ff1617919050565b60006111188260181c6bffffffffffffffffffffffff1690565b6111308360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600060f08083179060ff821690036111615750603092915050565b8060ff1660f1036111755750603192915050565b8060ff1660f2036111895750603292915050565b8060ff1660f30361119d5750603392915050565b8060ff1660f4036111b15750603492915050565b8060ff1660f5036111c55750603592915050565b8060ff1660f6036111d95750603692915050565b8060ff1660f7036111ed5750603792915050565b8060ff1660f8036112015750603892915050565b8060ff1660f9036112155750603992915050565b8060ff1660fa036112295750606192915050565b8060ff1660fb0361123d5750606292915050565b8060ff1660fc036112515750606392915050565b8060ff1660fd036112655750606492915050565b8060ff1660fe036112795750606592915050565b8060ff1660ff036105645750606692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126112cd57600080fd5b813567ffffffffffffffff808211156112e8576112e861128d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561132e5761132e61128d565b8160405283815286602085880101111561134757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561137957600080fd5b813567ffffffffffffffff81111561139057600080fd5b610708848285016112bc565b60005b838110156113b757818101518382015260200161139f565b838111156113c6576000848401525b50505050565b600081518084526113e481602086016020860161139c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105d460208301846113cc565b803563ffffffff8116811461143d57600080fd5b919050565b600080600080600080600080610100898b03121561145f57600080fd5b61146889611429565b97506020890135965061147d60408a01611429565b955061148b60608a01611429565b9450608089013593506114a060a08a01611429565b925060c089013567ffffffffffffffff808211156114bd57600080fd5b6114c98c838d016112bc565b935060e08b01359150808211156114df57600080fd5b506114ec8b828c016112bc565b9150509295985092959890939650565b80356bffffffffffffffffffffffff8116811461143d57600080fd5b60008060008060008060008060008060006101608c8e03121561153a57600080fd5b6115438c611429565b9a5060208c0135995061155860408d01611429565b985061156660608d01611429565b975060808c0135965061157b60a08d01611429565b955061158960c08d016114fc565b945061159760e08d016114fc565b93506115a66101008d016114fc565b92506115b56101208d016114fc565b91506101408c013567ffffffffffffffff8111156115d257600080fd5b6115de8e828f016112bc565b9150509295989b509295989b9093969950565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff84168160ff048111821515161561167057611670611620565b029392505050565b600061ffff80831681851680830382111561169557611695611620565b01949350505050565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516116fe81600885016020890161139c565b84519083019061171581600884016020890161139c565b845191019061172b81600884016020880161139c565b016008019998505050505050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561177457611774611620565b500290565b60008282101561178b5761178b611620565b500390565b600060ff821660ff8416808210156117aa576117aa611620565b90039392505050565b600082198211156117c6576117c6611620565b500190565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201610bca56fea26469706673582212200d433cf58b1c411e28dea26e6cfce55626c077761ae2aefdef024731ec7fd18464736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c806381d030ef1161008c578063c97c703a11610066578063c97c703a146101de578063cb3eb0e1146101f1578063d7a7a72c14610204578063f45387ba1461021757600080fd5b806381d030ef146101a5578063985a5c31146101b8578063c81aa9c8146101cb57600080fd5b806352617f3c116100c857806352617f3c14610161578063639c5570146101775780636dc3c4f71461017f5780637c1cfff91461019257600080fd5b8063045c6c0b146100ef57806346fad66e146101185780634e76500414610139575b600080fd5b6101026100fd366004611367565b61024f565b60405161010f9190611416565b60405180910390f35b61012b610126366004611442565b61027c565b60405190815260200161010f565b61014c610147366004611367565b61032b565b60405163ffffffff909116815260200161010f565b60015b60405161ffff909116815260200161010f565b610164610352565b61012b61018d366004611367565b610368565b61014c6101a0366004611367565b610384565b6101026101b3366004611518565b6103a0565b61012b6101c6366004611367565b610477565b61014c6101d9366004611367565b610493565b6101026101ec366004611367565b6104af565b61014c6101ff366004611367565b6104cb565b61012b610212366004611367565b6104e7565b61022a610225366004611367565b610500565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010f565b606061027661026b6102608461051c565b62ffffff191661052a565b62ffffff191661056a565b92915050565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e08b811b82166022840152602683018b905289811b8216604684015288811b8216604a840152604e830188905286901b16606e82015281518082036052018152607290910190915260009061031d8185856105bd565b9a9950505050505050505050565b600061027661034761033c8461051c565b62ffffff19166105db565b62ffffff1916610612565b60006103606004600261164f565b60ff16905090565b600061027661037961033c8461051c565b62ffffff191661063c565b600061027661039561033c8461051c565b62ffffff191661065d565b606060006103b08787878761067e565b905060006104588e8e8e8e8e8e604080517e01000000000000000000000000000000000000000000000000000000000000602082015260e097881b7fffffffff000000000000000000000000000000000000000000000000000000009081166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281516052818303018152607290910190915290565b9050610465818386610710565b9e9d5050505050505050505050505050565b600061027661048861033c8461051c565b62ffffff191661078a565b60006102766104a461033c8461051c565b62ffffff19166107ab565b606061027661026b6104c08461051c565b62ffffff19166107cc565b60006102766104dc61033c8461051c565b62ffffff191661080b565b60006102766104f58361051c565b62ffffff191661082c565b600061027661051161033c8461051c565b62ffffff1916610851565b600061027682610539610862565b60008161053f62ffffff198216610539610886565b506105618361054f8560026109aa565b61055a8660036109aa565b60026109dc565b91505b50919050565b60606000806105878460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506105ac84836020016109fb565b508181016020016040529052919050565b60006105ca848484610710565b8051906020012090505b9392505050565b6000816105f062ffffff198216610539610886565b50610561836106008560016109aa565b61060b8660026109aa565b60016109dc565b60008161062860015b62ffffff19831690610886565b5061056162ffffff19841660266004610bd4565b600081610649600161061b565b5061056162ffffff19841660066020610c04565b60008161066a600161061b565b5061056162ffffff198416604e6004610bd4565b6040517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a086811b8216602284015285811b8216602e84015284811b8216603a84015283901b16604682015260609060520160405160208183030381529060405290505b949350505050565b82516060906000906107246004600261164f565b60ff166107319190611678565b905060008451826107429190611678565b905060016107526004600261164f565b60ff168383898989604051602001610770979695949392919061169e565b604051602081830303815290604052925050509392505050565b600081610797600161061b565b5061056162ffffff198416602e6020610c04565b6000816107b8600161061b565b5061056162ffffff198416602a6004610bd4565b6000816107e162ffffff198216610539610886565b50610561836107f18560036109aa565b601886901c6bffffffffffffffffffffffff1660036109dc565b600081610818600161061b565b5061056162ffffff19841660026004610bd4565b60008161084162ffffff198216610539610886565b5061056162ffffff198416610df6565b600061027661085f8361078a565b90565b81516000906020840161087d64ffffffffff85168284610e53565b95945050505050565b60006108928383610e9a565b6109a35760006108b16108a58560d81c90565b64ffffffffff16610ebd565b91505060006108c68464ffffffffff16610ebd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60405180910390fd5b5090919050565b60006105d460028360048111156109c3576109c36115f1565b6109cd919061173c565b62ffffff198516906002610bd4565b600061087d846109ec8186611779565b62ffffff198816919085610fa7565b600062ffffff1980841603610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161099a565b610a9b83611021565b610b27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161099a565b6000610b418460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115610b905760206060fd5b8285848460045afa50610bca610ba68760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b6000610be1826020611790565b610bec90600861164f565b60ff16610bfa858585610c04565b901c949350505050565b60008160ff16600003610c19575060006105d4565b610c318460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c4c60ff8416856117b3565b1115610cde57610cab610c6d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c938660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661105e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60208260ff161115610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161099a565b600882026000610d908660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600080610e118360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610e3b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080610e6083856117b3565b9050604051811115610e70575060005b80600003610e855762ffffff199150506105d4565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16610eae8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115610f30576000610edc82600861164f565b60ff1685901c9050610eed816110cc565b61ffff16841793508160ff16601014610f0857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610ec3565b50600f5b60ff8160ff161015610fa1576000610f4d82600861164f565b60ff1685901c9050610f5e816110cc565b61ffff16831792508160ff16600014610f7957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610f34565b50915091565b600080610fc28660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050610fdb866110fe565b84610fe687846117b3565b610ff091906117b3565b11156110035762ffffff19915050610708565b61100d85826117b3565b9050610bca8364ffffffffff168286610e53565b600061102d8260d81c90565b64ffffffffff1664ffffffffff0361104757506000919050565b6000611052836110fe565b60405110199392505050565b6060600061106b86610ebd565b915050600061107986610ebd565b915050600061108786610ebd565b915050600061109586610ebd565b915050838383836040516020016110af94939291906117cb565b604051602081830303815290604052945050505050949350505050565b60006110de60048360ff16901c611146565b60ff1661ffff919091161760081b6110f582611146565b60ff1617919050565b60006111188260181c6bffffffffffffffffffffffff1690565b6111308360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600060f08083179060ff821690036111615750603092915050565b8060ff1660f1036111755750603192915050565b8060ff1660f2036111895750603292915050565b8060ff1660f30361119d5750603392915050565b8060ff1660f4036111b15750603492915050565b8060ff1660f5036111c55750603592915050565b8060ff1660f6036111d95750603692915050565b8060ff1660f7036111ed5750603792915050565b8060ff1660f8036112015750603892915050565b8060ff1660f9036112155750603992915050565b8060ff1660fa036112295750606192915050565b8060ff1660fb0361123d5750606292915050565b8060ff1660fc036112515750606392915050565b8060ff1660fd036112655750606492915050565b8060ff1660fe036112795750606592915050565b8060ff1660ff036105645750606692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126112cd57600080fd5b813567ffffffffffffffff808211156112e8576112e861128d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561132e5761132e61128d565b8160405283815286602085880101111561134757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561137957600080fd5b813567ffffffffffffffff81111561139057600080fd5b610708848285016112bc565b60005b838110156113b757818101518382015260200161139f565b838111156113c6576000848401525b50505050565b600081518084526113e481602086016020860161139c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105d460208301846113cc565b803563ffffffff8116811461143d57600080fd5b919050565b600080600080600080600080610100898b03121561145f57600080fd5b61146889611429565b97506020890135965061147d60408a01611429565b955061148b60608a01611429565b9450608089013593506114a060a08a01611429565b925060c089013567ffffffffffffffff808211156114bd57600080fd5b6114c98c838d016112bc565b935060e08b01359150808211156114df57600080fd5b506114ec8b828c016112bc565b9150509295985092959890939650565b80356bffffffffffffffffffffffff8116811461143d57600080fd5b60008060008060008060008060008060006101608c8e03121561153a57600080fd5b6115438c611429565b9a5060208c0135995061155860408d01611429565b985061156660608d01611429565b975060808c0135965061157b60a08d01611429565b955061158960c08d016114fc565b945061159760e08d016114fc565b93506115a66101008d016114fc565b92506115b56101208d016114fc565b91506101408c013567ffffffffffffffff8111156115d257600080fd5b6115de8e828f016112bc565b9150509295989b509295989b9093969950565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff84168160ff048111821515161561167057611670611620565b029392505050565b600061ffff80831681851680830382111561169557611695611620565b01949350505050565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516116fe81600885016020890161139c565b84519083019061171581600884016020890161139c565b845191019061172b81600884016020880161139c565b016008019998505050505050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561177457611774611620565b500290565b60008282101561178b5761178b611620565b500390565b600060ff821660ff8416808210156117aa576117aa611620565b90039392505050565b600082198211156117c6576117c6611620565b500190565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201610bca56fea26469706673582212200d433cf58b1c411e28dea26e6cfce55626c077761ae2aefdef024731ec7fd18464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(\n _updaterTip,\n _relayerTip,\n _proverTip,\n _processorTip\n );\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44669:3701:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"44669:3701:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46713:135;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46158:549;;;;;;:::i;:::-;;:::i;:::-;;;3403:25:1;;;3391:2;3376:18;46158:549:0;3257:177:1;47276:132:0;;;;;;:::i;:::-;;:::i;:::-;;;3613:10:1;3601:23;;;3583:42;;3571:2;3556:18;47276:132:0;3439:192:1;48162:102:0;33745:1;48162:102;;;3810:6:1;3798:19;;;3780:38;;3768:2;3753:18;48162:102:0;3636:188:1;48270:98:0;;;:::i;47135:135::-;;;;;;:::i;:::-;;:::i;47872:156::-;;;;;;:::i;:::-;;:::i;44826:862::-;;;;;;:::i;:::-;;:::i;47564:141::-;;;;;;:::i;:::-;;:::i;47414:144::-;;;;;;:::i;:::-;;:::i;46854:135::-;;;;;;:::i;:::-;;:::i;46995:134::-;;;;;;:::i;:::-;;:::i;48034:122::-;;;;;;:::i;:::-;;:::i;47711:155::-;;;;;;:::i;:::-;;:::i;:::-;;;5236:42:1;5224:55;;;5206:74;;5194:2;5179:18;47711:155:0;5060:226:1;46713:135:0;46773:12;46804:37;:29;:22;:8;:20;:22::i;:::-;-1:-1:-1;;46804:27:0;;:29::i;:::-;-1:-1:-1;;46804:35:0;;:37::i;:::-;46797:44;46713:135;-1:-1:-1;;46713:135:0:o;46158:549::-;39644:242;;;6215:16:1;39644:242:0;;;6199:102:1;6320:66;6423:3;6419:16;;;6415:25;;6402:11;;;6395:46;6457:11;;;6450:27;;;6511:16;;;6507:25;;6493:12;;;6486:47;6567:16;;;6563:25;;6549:12;;;6542:47;6605:12;;;6598:28;;;6660:16;;;6656:25;6642:12;;;6635:47;39644:242:0;;;;;;;;;6698:12:1;;;;39644:242:0;;;46426:7;;46658:42;46678:7;46687:5;46694;46658:19;:42::i;:::-;46651:49;46158:549;-1:-1:-1;;;;;;;;;;46158:549:0:o;47276:132::-;47337:6;47362:39;:31;:22;:8;:20;:22::i;:::-;-1:-1:-1;;47362:29:0;;:31::i;:::-;-1:-1:-1;;47362:37:0;;:39::i;48270:98::-;48315:6;35024:29;35042:10;34895:1;35024:29;:::i;:::-;48340:21;;48333:28;;48270:98;:::o;47135:135::-;47197:7;47223:40;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47223:38:0;;:40::i;47872:156::-;47945:6;47970:51;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47970:49:0;;:51::i;44826:862::-;45223:12;45247:18;45268:126;45297:11;45322;45347:10;45371:13;45268:15;:126::i;:::-;45247:147;;45405:20;45428:185;45461:13;45488:7;45509:6;45529:18;45561:10;45585:18;39644:242;;;6215:16:1;39644:242:0;;;6199:102:1;6423:3;6419:16;;;6320:66;6415:25;;;6402:11;;;6395:46;6457:11;;;6450:27;;;;6511:16;;;6507:25;;6493:12;;;6486:47;6567:16;;;6563:25;;6549:12;;;6542:47;6605:12;;;6598:28;;;;6660:16;;;6656:25;;;6642:12;;;6635:47;39644:242:0;;;;;;;;;6698:12:1;;;;39644:242:0;;;;39374:519;45428:185;45405:208;;45630:51;45652:7;45661:5;45668:12;45630:21;:51::i;:::-;45623:58;44826:862;-1:-1:-1;;;;;;;;;;;;;;44826:862:0:o;47564:141::-;47629:7;47655:43;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47655:41:0;;:43::i;47414:144::-;47481:6;47506:45;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47506:43:0;;:45::i;46854:135::-;46914:12;46945:37;:29;:22;:8;:20;:22::i;:::-;-1:-1:-1;;46945:27:0;;:29::i;46995:134::-;47057:6;47082:40;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47082:38:0;;:40::i;48034:122::-;48094:7;48120:29;:22;:8;:20;:22::i;:::-;-1:-1:-1;;48120:27:0;;:29::i;47711:155::-;47783:7;47809:50;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47809:48:0;;:50::i;36381:126::-;36448:7;36474:26;:8;33969:4;36474:12;:26::i;37058:299::-;37135:7;37116:8;34213:30;-1:-1:-1;;34213:16:0;;33969:4;34213:16;:30::i;:::-;;37173:177:::1;37199:8;37225:33;37237:8;37247:10;37225:11;:33::i;:::-;37276;37288:8;37298:10;37276:11;:33::i;:::-;34088:10;37173:8;:177::i;:::-;37154:196;;34253:1;37058:299:::0;;;;:::o;28308:632::-;28363:16;28391:11;28412:12;28427;28431:7;16492:2;16488:16;2670:26;16484:28;;16246:282;28427:12;28412:27;;;;28549:4;28543:11;28536:18;;28604:3;28597:10;;28650:33;28663:7;28672:3;28678:4;28672:10;28650:12;:33::i;:::-;-1:-1:-1;28807:14:0;;;28823:4;28803:25;28797:4;28790:39;28870:17;;28308:632;;-1:-1:-1;28308:632:0:o;36145:230::-;36288:7;36324:43;36338:7;36347:5;36354:12;36324:13;:43::i;:::-;36314:54;;;;;;36307:61;;36145:230;;;;;;:::o;36631:305::-;36710:7;36691:8;34213:30;-1:-1:-1;;34213:16:0;;33969:4;34213:16;:30::i;:::-;;36748:181:::1;36774:8;36800:35;36812:8;36822:12;36800:11;:35::i;:::-;36853:33;36865:8;36875:10;36853:11;:33::i;:::-;34025:12;37173:8;:177::i;40628:149::-:0;40703:6;40685:7;39313:37;34025:12;34018:20;-1:-1:-1;;39313:16:0;;;;:37::i;:::-;-1:-1:-1;40735:34:0::1;-1:-1:-1::0;;40735:17:0;::::1;39089:2;40767:1;40735:17;:34::i;40436:141::-:0;40512:7;40494;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;40538:32:0::1;-1:-1:-1::0;;40538:13:0;::::1;39041:1;40567:2;40538:13;:32::i;41272:174::-:0;41359:6;41341:7;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;41391:47:0::1;-1:-1:-1::0;;41391:17:0;::::1;39259:2;41436:1;41391:17;:47::i;42738:283::-:0;42931:83;;6968:16:1;42931:83:0;;;6952:102:1;7073:66;7176:3;7172:16;;;7168:25;;7155:11;;;7148:46;7228:16;;;7224:25;;7210:12;;;7203:47;7284:16;;;7280:25;;7266:12;;;7259:47;7340:16;;;7336:25;7322:12;;;7315:47;42900:12:0;;7378::1;;42931:83:0;;;;;;;;;;;;42924:90;;42738:283;;;;;;;:::o;35273:638::-;35569:14;;35418:12;;35526:17;;35024:29;35042:10;34895:1;35024:29;:::i;:::-;35546:13;;:38;;;;:::i;:::-;35526:58;;35594:17;35634:5;:12;35614:10;:33;;;;:::i;:::-;35594:53;-1:-1:-1;33745:1:0;35024:29;35042:10;34895:1;35024:29;:::i;:::-;35743:13;;35774:10;35802;35830:7;35855:5;35878:12;35676:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;35657:247;;;;35273:638;;;;;:::o;41061:147::-;41140:7;41122;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;41166:35:0::1;-1:-1:-1::0;;41166:13:0;::::1;39197:2;41198;41166:13;:35::i;40834:161::-:0;40915:6;40897:7;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;40947:40:0::1;-1:-1:-1::0;;40947:17:0;::::1;39144:2;40985:1;40947:17;:40::i;37479:190::-:0;37556:7;37537:8;34213:30;-1:-1:-1;;34213:16:0;;33969:4;34213:16;:30::i;:::-;;37582:80:::1;37591:8;37601:33;37613:8;37623:10;37601:11;:33::i;:::-;16492:2:::0;16488:16;;;2670:26;16484:28;34149:10:::1;37173:8;:177::i;40233:151::-:0;40309:6;40291:7;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;40341:35:0::1;-1:-1:-1::0;;40341:17:0;::::1;38992:1;40374;40341:17;:35::i;37730:170::-:0;37807:7;37788:8;34213:30;-1:-1:-1;;34213:16:0;;33969:4;34213:16;:30::i;:::-;-1:-1:-1;37876:17:0::1;-1:-1:-1::0;;37876:15:0;::::1;;:17::i;41515:145::-:0;41581:7;41607:46;41634:18;41644:7;41634:9;:18::i;:::-;33368:4;33255:127;13655:359;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;:::-;13974:33;13655:359;-1:-1:-1;;;;;13655:359:0:o;10073:578::-;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;9075:31:1;10385:186:0;;;9063:44:1;9126:66;9230:3;9226:16;;;9222:25;;9208:12;;;9201:47;9278:15;9264:12;;;9257:37;9328:16;;;9324:25;9310:12;;;9303:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;9366:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;;;;;;;;;;:::i;:::-;;;;;;;;10170:451;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;38191:164::-;38265:7;38291:57;34895:1;38318:5;38310:14;;;;;;;;:::i;:::-;:26;;;;:::i;:::-;-1:-1:-1;;38291:18:0;;;34895:1;38291:18;:57::i;37906:218::-;38047:7;38073:44;38088:5;38095:11;38088:5;38095:3;:11;:::i;:::-;-1:-1:-1;;38073:14:0;;;:44;38108:8;38073:14;:44::i;27036:902::-;27114:15;-1:-1:-1;;7972:15:0;;;;27141:69;;;;;;;10178:2:1;27141:69:0;;;10160:21:1;10217:2;10197:18;;;10190:30;10256:34;10236:18;;;10229:62;10327:10;10307:18;;;10300:38;10355:19;;27141:69:0;9976:404:1;27141:69:0;27228:16;27236:7;27228;:16::i;:::-;27220:72;;;;;;;10587:2:1;27220:72:0;;;10569:21:1;10626:2;10606:18;;;10599:30;10665:34;10645:18;;;10638:62;10736:13;10716:18;;;10709:41;10767:19;;27220:72:0;10385:407:1;27220:72:0;27302:12;27317;27321:7;16492:2;16488:16;2670:26;16484:28;;16246:282;27317:12;27302:27;;;;27339:15;27357:12;27361:7;15386:3;15382:17;2670:26;15378:29;;15059:364;27357:12;27339:30;;;;27380:11;27501:4;27495:11;27488:18;;27588:7;27583:3;27580:16;27577:94;;;27628:4;27622;27615:18;27577:94;27843:4;27834:7;27828:4;27819:7;27816:1;27809:5;27798:50;27794:55;27879:52;27900:15;27907:7;14417:3;14413:17;;14206:268;27900:15;12061:27;12065:2;12061:27;;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;;11811:446;27879:52;27869:62;27036:902;-1:-1:-1;;;;;;27036:902:0:o;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;;;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;;;;11332:2:1;20359:83:0;;;11314:21:1;11371:2;11351:18;;;11344:30;11410:34;11390:18;;;11383:62;11481:28;11461:18;;;11454:56;11527:19;;20359:83:0;11130:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;22455:290::-;22511:14;22537:12;22552;22556:7;15386:3;15382:17;2670:26;15378:29;;15059:364;22552:12;22537:27;;;;22574:12;22589;22593:7;16492:2;16488:16;2670:26;16484:28;;16246:282;22589:12;22574:27;;22708:21;;;;22455:290;-1:-1:-1;;;22455:290:0:o;12796:462::-;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;-1:-1:-1;;12065:2:0;12061:27;;;12135:17;;;;12127:26;;;12199:17;12195:2;12191:26;;12796:462::o;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;17129:399::-;17268:7;17287:12;17302;17306:7;15386:3;15382:17;2670:26;15378:29;;15059:364;17302:12;17287:27;;;;17398:12;17402:7;17398:3;:12::i;:::-;17391:4;17375:13;17382:6;17375:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17371:77;;;-1:-1:-1;;17426:11:0;;;;;17371:77;17465:13;17472:6;17465:4;:13;:::i;:::-;17458:20;;17495:26;17501:7;17495:26;;17510:4;17516;17495:5;:26::i;8645:333::-;8702:8;8726:15;8733:7;14417:3;14413:17;;14206:268;8726:15;:31;;8745:12;8726:31;8722:74;;-1:-1:-1;8780:5:0;;8645:333;-1:-1:-1;8645:333:0:o;8722:74::-;8805:12;8820;8824:7;8820:3;:12::i;:::-;8955:4;8949:11;-1:-1:-1;8936:26:0;;8645:333;-1:-1:-1;;;8645:333:0:o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19061:33;;;19244:1;19306;19386;19448;19130:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19104:391;;18926:576;;;;18761:741;;;;;;:::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;16702:147::-;16755:7;16820:12;16824:7;16492:2;16488:16;2670:26;16484:28;;16246:282;16820:12;16805;16809:7;15386:3;15382:17;2670:26;15378:29;;15059:364;16805:12;:27;16798:34;;;;16702:147;;;:::o;2943:1393::-;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;14:184:1:-;66:77;63:1;56:88;163:4;160:1;153:15;187:4;184:1;177:15;203:777;245:5;298:3;291:4;283:6;279:17;275:27;265:55;;316:1;313;306:12;265:55;352:6;339:20;378:18;415:2;411;408:10;405:36;;;421:18;;:::i;:::-;555:2;549:9;617:4;609:13;;460:66;605:22;;;629:2;601:31;597:40;585:53;;;653:18;;;673:22;;;650:46;647:72;;;699:18;;:::i;:::-;739:10;735:2;728:22;774:2;766:6;759:18;820:3;813:4;808:2;800:6;796:15;792:26;789:35;786:55;;;837:1;834;827:12;786:55;901:2;894:4;886:6;882:17;875:4;867:6;863:17;850:54;948:1;941:4;936:2;928:6;924:15;920:26;913:37;968:6;959:15;;;;;;203:777;;;;:::o;985:320::-;1053:6;1106:2;1094:9;1085:7;1081:23;1077:32;1074:52;;;1122:1;1119;1112:12;1074:52;1162:9;1149:23;1195:18;1187:6;1184:30;1181:50;;;1227:1;1224;1217:12;1181:50;1250:49;1291:7;1282:6;1271:9;1267:22;1250:49;:::i;1310:258::-;1382:1;1392:113;1406:6;1403:1;1400:13;1392:113;;;1482:11;;;1476:18;1463:11;;;1456:39;1428:2;1421:10;1392:113;;;1523:6;1520:1;1517:13;1514:48;;;1558:1;1549:6;1544:3;1540:16;1533:27;1514:48;;1310:258;;;:::o;1573:316::-;1614:3;1652:5;1646:12;1679:6;1674:3;1667:19;1695:63;1751:6;1744:4;1739:3;1735:14;1728:4;1721:5;1717:16;1695:63;:::i;:::-;1803:2;1791:15;1808:66;1787:88;1778:98;;;;1878:4;1774:109;;1573:316;-1:-1:-1;;1573:316:1:o;1894:217::-;2041:2;2030:9;2023:21;2004:4;2061:44;2101:2;2090:9;2086:18;2078:6;2061:44;:::i;2116:163::-;2183:20;;2243:10;2232:22;;2222:33;;2212:61;;2269:1;2266;2259:12;2212:61;2116:163;;;:::o;2284:968::-;2420:6;2428;2436;2444;2452;2460;2468;2476;2529:3;2517:9;2508:7;2504:23;2500:33;2497:53;;;2546:1;2543;2536:12;2497:53;2569:28;2587:9;2569:28;:::i;:::-;2559:38;;2644:2;2633:9;2629:18;2616:32;2606:42;;2667:37;2700:2;2689:9;2685:18;2667:37;:::i;:::-;2657:47;;2723:37;2756:2;2745:9;2741:18;2723:37;:::i;:::-;2713:47;;2807:3;2796:9;2792:19;2779:33;2769:43;;2831:38;2864:3;2853:9;2849:19;2831:38;:::i;:::-;2821:48;;2920:3;2909:9;2905:19;2892:33;2944:18;2985:2;2977:6;2974:14;2971:34;;;3001:1;2998;2991:12;2971:34;3024:49;3065:7;3056:6;3045:9;3041:22;3024:49;:::i;:::-;3014:59;;3126:3;3115:9;3111:19;3098:33;3082:49;;3156:2;3146:8;3143:16;3140:36;;;3172:1;3169;3162:12;3140:36;;3195:51;3238:7;3227:8;3216:9;3212:24;3195:51;:::i;:::-;3185:61;;;2284:968;;;;;;;;;;;:::o;3829:179::-;3896:20;;3956:26;3945:38;;3935:49;;3925:77;;3998:1;3995;3988:12;4013:1042;4163:6;4171;4179;4187;4195;4203;4211;4219;4227;4235;4243:7;4297:3;4285:9;4276:7;4272:23;4268:33;4265:53;;;4314:1;4311;4304:12;4265:53;4337:28;4355:9;4337:28;:::i;:::-;4327:38;;4412:2;4401:9;4397:18;4384:32;4374:42;;4435:37;4468:2;4457:9;4453:18;4435:37;:::i;:::-;4425:47;;4491:37;4524:2;4513:9;4509:18;4491:37;:::i;:::-;4481:47;;4575:3;4564:9;4560:19;4547:33;4537:43;;4599:38;4632:3;4621:9;4617:19;4599:38;:::i;:::-;4589:48;;4656:38;4689:3;4678:9;4674:19;4656:38;:::i;:::-;4646:48;;4713:38;4746:3;4735:9;4731:19;4713:38;:::i;:::-;4703:48;;4770:38;4803:3;4792:9;4788:19;4770:38;:::i;:::-;4760:48;;4827:38;4860:3;4849:9;4845:19;4827:38;:::i;:::-;4817:48;;4916:3;4905:9;4901:19;4888:33;4944:18;4936:6;4933:30;4930:50;;;4976:1;4973;4966:12;4930:50;5000:49;5041:7;5032:6;5021:9;5017:22;5000:49;:::i;:::-;4989:60;;;4013:1042;;;;;;;;;;;;;;:::o;5291:184::-;5343:77;5340:1;5333:88;5440:4;5437:1;5430:15;5464:4;5461:1;5454:15;5480:184;5532:77;5529:1;5522:88;5629:4;5626:1;5619:15;5653:4;5650:1;5643:15;5669:238;5707:7;5747:4;5744:1;5740:12;5779:4;5776:1;5772:12;5839:3;5833:4;5829:14;5824:3;5821:23;5814:3;5807:11;5800:19;5796:49;5793:75;;;5848:18;;:::i;:::-;5888:13;;5669:238;-1:-1:-1;;;5669:238:1:o;7401:224::-;7440:3;7468:6;7501:2;7498:1;7494:10;7531:2;7528:1;7524:10;7562:3;7558:2;7554:12;7549:3;7546:21;7543:47;;;7570:18;;:::i;:::-;7606:13;;7401:224;-1:-1:-1;;;;7401:224:1:o;7630:1073::-;7955:3;7983:66;8092:2;8083:6;8078:3;8074:16;8070:25;8065:3;8058:38;8147:2;8138:6;8133:3;8129:16;8125:25;8121:1;8116:3;8112:11;8105:46;8202:2;8193:6;8188:3;8184:16;8180:25;8176:1;8171:3;8167:11;8160:46;8257:2;8248:6;8243:3;8239:16;8235:25;8231:1;8226:3;8222:11;8215:46;;8290:6;8284:13;8306:61;8360:6;8356:1;8351:3;8347:11;8340:4;8332:6;8328:17;8306:61;:::i;:::-;8427:13;;8386:16;;;;8449:62;8427:13;8498:1;8490:10;;8483:4;8471:17;;8449:62;:::i;:::-;8572:13;;8530:17;;;8594:62;8572:13;8643:1;8635:10;;8628:4;8616:17;;8594:62;:::i;:::-;8676:17;8695:1;8672:25;;7630:1073;-1:-1:-1;;;;;;;;;7630:1073:1:o;9613:228::-;9653:7;9779:1;9711:66;9707:74;9704:1;9701:81;9696:1;9689:9;9682:17;9678:105;9675:131;;;9786:18;;:::i;:::-;-1:-1:-1;9826:9:1;;9613:228::o;9846:125::-;9886:4;9914:1;9911;9908:8;9905:34;;;9919:18;;:::i;:::-;-1:-1:-1;9956:9:1;;9846:125::o;10797:195::-;10835:4;10872;10869:1;10865:12;10904:4;10901:1;10897:12;10929:3;10924;10921:12;10918:38;;;10936:18;;:::i;:::-;10973:13;;;10797:195;-1:-1:-1;;;10797:195:1:o;10997:128::-;11037:3;11068:1;11064:6;11061:1;11058:13;11055:39;;;11074:18;;:::i;:::-;-1:-1:-1;11110:9:1;;10997:128::o;11676:1391::-;12398:34;12386:47;;12463:23;12458:2;12449:12;;12442:45;12506:66;12610:3;12606:16;;;12602:25;;12597:2;12588:12;;12581:47;12647:17;12689:2;12680:12;;12673:24;;;12731:16;;;12727:25;;12722:2;12713:12;;12706:47;12783:34;12778:2;12769:12;;12762:56;12849:3;12843;12834:13;;12827:26;12888:16;;;12884:25;;12878:3;12869:13;;12862:48;12935:3;12926:13;;12919:25;12979:16;;;12975:25;12969:3;12960:13;;12953:48;11634:3;13056;13047:13;;11622:16;-1:-1:-1;11654:11:1;;;13017:44;11557:114","abiDefinition":[{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"body","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"destination","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_originDomain","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"uint96","name":"_updaterTip","type":"uint96"},{"internalType":"uint96","name":"_relayerTip","type":"uint96"},{"internalType":"uint96","name":"_proverTip","type":"uint96"},{"internalType":"uint96","name":"_processorTip","type":"uint96"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"formatMessage","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"headerOffset","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"leaf","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_origin","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint32","name":"_destination","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_body","type":"bytes"}],"name":"messageHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"messageVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"optimisticSeconds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"origin","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"recipient","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"recipientAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"sender","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"tips","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{"messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)":{"notice":"Returns leaf of formatted message with provided fields."}},"version":1},"developerDoc":{"kind":"dev","methods":{"messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)":{"params":{"_body":"Raw bytes of message body","_destination":"Domain of destination chain","_nonce":"Destination-specific nonce number","_origin":"Domain of home chain","_recipient":"Address of recipient on destination chain as bytes32","_sender":"Address of sender as bytes32"},"returns":{"_0":"Leaf (hash) of formatted message*"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"body\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"destination\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_originDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipient\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"_updaterTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_relayerTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_proverTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_processorTip\",\"type\":\"uint96\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"formatMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"headerOffset\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"leaf\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_destination\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipient\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_body\",\"type\":\"bytes\"}],\"name\":\"messageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"optimisticSeconds\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"origin\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"recipient\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"recipientAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"sender\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"tips\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)\":{\"params\":{\"_body\":\"Raw bytes of message body\",\"_destination\":\"Domain of destination chain\",\"_nonce\":\"Destination-specific nonce number\",\"_origin\":\"Domain of home chain\",\"_recipient\":\"Address of recipient on destination chain as bytes32\",\"_sender\":\"Address of sender as bytes32\"},\"returns\":{\"_0\":\"Leaf (hash) of formatted message*\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Returns leaf of formatted message with provided fields.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"MessageHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0xd56bf4956dacf8171f3ad4aeb3a5b7d8caa7cbe9e8b69dfc8d9bd876eebd9a72\",\"urls\":[\"bzz-raw://ddfeebc4974db727553a7ca169c2faa33d43beeb304939917f1452adf389c71b\",\"dweb:/ipfs/QmS8RKA433rvBfZwRkF8JkTHbQi5X7a4ArQQo3wcwaTeuj\"]}},\"version\":1}"},"hashes":{"body(bytes)":"c97c703a","destination(bytes)":"c81aa9c8","formatMessage(uint32,bytes32,uint32,uint32,bytes32,uint32,uint96,uint96,uint96,uint96,bytes)":"81d030ef","headerOffset()":"639c5570","leaf(bytes)":"d7a7a72c","messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)":"46fad66e","messageVersion()":"52617f3c","nonce(bytes)":"4e765004","optimisticSeconds(bytes)":"7c1cfff9","origin(bytes)":"cb3eb0e1","recipient(bytes)":"985a5c31","recipientAddress(bytes)":"f45387ba","sender(bytes)":"6dc3c4f7","tips(bytes)":"045c6c0b"}},"solidity/MessageHarness.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b0756d9546e7b2b4430f26d5c0341e164889948353dd82e994099eb78e3d3c6f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b0756d9546e7b2b4430f26d5c0341e164889948353dd82e994099eb78e3d3c6f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(\n _updaterTip,\n _relayerTip,\n _proverTip,\n _processorTip\n );\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"41664:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;41664:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"41664:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0xd56bf4956dacf8171f3ad4aeb3a5b7d8caa7cbe9e8b69dfc8d9bd876eebd9a72\",\"urls\":[\"bzz-raw://ddfeebc4974db727553a7ca169c2faa33d43beeb304939917f1452adf389c71b\",\"dweb:/ipfs/QmS8RKA433rvBfZwRkF8JkTHbQi5X7a4ArQQo3wcwaTeuj\"]}},\"version\":1}"},"hashes":{}},"solidity/MessageHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c35e25f0946b278c613f5ebbafe60a8a7c609ce7200241743e59bf36c324e16f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c35e25f0946b278c613f5ebbafe60a8a7c609ce7200241743e59bf36c324e16f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(\n _updaterTip,\n _relayerTip,\n _proverTip,\n _processorTip\n );\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32274:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32274:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32274:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0xd56bf4956dacf8171f3ad4aeb3a5b7d8caa7cbe9e8b69dfc8d9bd876eebd9a72\",\"urls\":[\"bzz-raw://ddfeebc4974db727553a7ca169c2faa33d43beeb304939917f1452adf389c71b\",\"dweb:/ipfs/QmS8RKA433rvBfZwRkF8JkTHbQi5X7a4ArQQo3wcwaTeuj\"]}},\"version\":1}"},"hashes":{}},"solidity/MessageHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220c22f1018f82777d7b0a5e7495d6d8c35c5962e2ace30e17414b6ee6723f7aaad64736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220c22f1018f82777d7b0a5e7495d6d8c35c5962e2ace30e17414b6ee6723f7aaad64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(\n _updaterTip,\n _relayerTip,\n _proverTip,\n _processorTip\n );\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0xd56bf4956dacf8171f3ad4aeb3a5b7d8caa7cbe9e8b69dfc8d9bd876eebd9a72\",\"urls\":[\"bzz-raw://ddfeebc4974db727553a7ca169c2faa33d43beeb304939917f1452adf389c71b\",\"dweb:/ipfs/QmS8RKA433rvBfZwRkF8JkTHbQi5X7a4ArQQo3wcwaTeuj\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}}} \ No newline at end of file +{"solidity/MessageHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122079285bd073ccdc689299532d711fd90f40c2f0c8d68ab95eb0317e06a7a5ca2064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122079285bd073ccdc689299532d711fd90f40c2f0c8d68ab95eb0317e06a7a5ca2064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"38359:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;38359:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"38359:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0x9a175023e8877c248b3f22cf08da899c122f6c8a5035509de971715be1c01547\",\"urls\":[\"bzz-raw://aa51718c01e07a0176734750853816ff2d24b343c60af773db6d51d7b0f62f3e\",\"dweb:/ipfs/QmW5EWU8AcHm9SeEPiijmHonWuau17KFmuFD53hftknuGc\"]}},\"version\":1}"},"hashes":{}},"solidity/MessageHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d372489e722a522548452efb606a042af02f9ebfa707cfcd9dbed3f510387eca64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d372489e722a522548452efb606a042af02f9ebfa707cfcd9dbed3f510387eca64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33386:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33386:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33386:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0x9a175023e8877c248b3f22cf08da899c122f6c8a5035509de971715be1c01547\",\"urls\":[\"bzz-raw://aa51718c01e07a0176734750853816ff2d24b343c60af773db6d51d7b0f62f3e\",\"dweb:/ipfs/QmW5EWU8AcHm9SeEPiijmHonWuau17KFmuFD53hftknuGc\"]}},\"version\":1}"},"hashes":{}},"solidity/MessageHarness.sol:MessageHarness":{"code":"0x608060405234801561001057600080fd5b5061193e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806381d030ef1161008c578063c97c703a11610066578063c97c703a146101de578063cb3eb0e1146101f1578063d7a7a72c14610204578063f45387ba1461021757600080fd5b806381d030ef146101a5578063985a5c31146101b8578063c81aa9c8146101cb57600080fd5b806352617f3c116100c857806352617f3c14610161578063639c5570146101775780636dc3c4f71461017f5780637c1cfff91461019257600080fd5b8063045c6c0b146100ef57806346fad66e146101185780634e76500414610139575b600080fd5b6101026100fd366004611367565b61024f565b60405161010f9190611416565b60405180910390f35b61012b610126366004611442565b61027c565b60405190815260200161010f565b61014c610147366004611367565b61032b565b60405163ffffffff909116815260200161010f565b60015b60405161ffff909116815260200161010f565b610164610352565b61012b61018d366004611367565b610368565b61014c6101a0366004611367565b610384565b6101026101b3366004611518565b6103a0565b61012b6101c6366004611367565b610477565b61014c6101d9366004611367565b610493565b6101026101ec366004611367565b6104af565b61014c6101ff366004611367565b6104cb565b61012b610212366004611367565b6104e7565b61022a610225366004611367565b610500565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010f565b606061027661026b6102608461051c565b62ffffff191661052a565b62ffffff191661056a565b92915050565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e08b811b82166022840152602683018b905289811b8216604684015288811b8216604a840152604e830188905286901b16606e82015281518082036052018152607290910190915260009061031d8185856105bd565b9a9950505050505050505050565b600061027661034761033c8461051c565b62ffffff19166105db565b62ffffff1916610612565b60006103606004600261164f565b60ff16905090565b600061027661037961033c8461051c565b62ffffff191661063c565b600061027661039561033c8461051c565b62ffffff191661065d565b606060006103b08787878761067e565b905060006104588e8e8e8e8e8e604080517e01000000000000000000000000000000000000000000000000000000000000602082015260e097881b7fffffffff000000000000000000000000000000000000000000000000000000009081166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281516052818303018152607290910190915290565b9050610465818386610710565b9e9d5050505050505050505050505050565b600061027661048861033c8461051c565b62ffffff191661078a565b60006102766104a461033c8461051c565b62ffffff19166107ab565b606061027661026b6104c08461051c565b62ffffff19166107cc565b60006102766104dc61033c8461051c565b62ffffff191661080b565b60006102766104f58361051c565b62ffffff191661082c565b600061027661051161033c8461051c565b62ffffff1916610851565b600061027682610539610862565b60008161053f62ffffff198216610539610886565b506105618361054f8560026109aa565b61055a8660036109aa565b60026109dc565b91505b50919050565b60606000806105878460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506105ac84836020016109fb565b508181016020016040529052919050565b60006105ca848484610710565b8051906020012090505b9392505050565b6000816105f062ffffff198216610539610886565b50610561836106008560016109aa565b61060b8660026109aa565b60016109dc565b60008161062860015b62ffffff19831690610886565b5061056162ffffff19841660266004610bd4565b600081610649600161061b565b5061056162ffffff19841660066020610c04565b60008161066a600161061b565b5061056162ffffff198416604e6004610bd4565b6040517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a086811b8216602284015285811b8216602e84015284811b8216603a84015283901b16604682015260609060520160405160208183030381529060405290505b949350505050565b82516060906000906107246004600261164f565b60ff166107319190611678565b905060008451826107429190611678565b905060016107526004600261164f565b60ff168383898989604051602001610770979695949392919061169e565b604051602081830303815290604052925050509392505050565b600081610797600161061b565b5061056162ffffff198416602e6020610c04565b6000816107b8600161061b565b5061056162ffffff198416602a6004610bd4565b6000816107e162ffffff198216610539610886565b50610561836107f18560036109aa565b601886901c6bffffffffffffffffffffffff1660036109dc565b600081610818600161061b565b5061056162ffffff19841660026004610bd4565b60008161084162ffffff198216610539610886565b5061056162ffffff198416610df6565b600061027661085f8361078a565b90565b81516000906020840161087d64ffffffffff85168284610e53565b95945050505050565b60006108928383610e9a565b6109a35760006108b16108a58560d81c90565b64ffffffffff16610ebd565b91505060006108c68464ffffffffff16610ebd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60405180910390fd5b5090919050565b60006105d460028360048111156109c3576109c36115f1565b6109cd919061173c565b62ffffff198516906002610bd4565b600061087d846109ec8186611779565b62ffffff198816919085610fa7565b600062ffffff1980841603610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161099a565b610a9b83611021565b610b27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161099a565b6000610b418460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115610b905760206060fd5b8285848460045afa50610bca610ba68760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b6000610be1826020611790565b610bec90600861164f565b60ff16610bfa858585610c04565b901c949350505050565b60008160ff16600003610c19575060006105d4565b610c318460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c4c60ff8416856117b3565b1115610cde57610cab610c6d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c938660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661105e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60208260ff161115610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161099a565b600882026000610d908660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600080610e118360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610e3b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080610e6083856117b3565b9050604051811115610e70575060005b80600003610e855762ffffff199150506105d4565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16610eae8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115610f30576000610edc82600861164f565b60ff1685901c9050610eed816110cc565b61ffff16841793508160ff16601014610f0857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610ec3565b50600f5b60ff8160ff161015610fa1576000610f4d82600861164f565b60ff1685901c9050610f5e816110cc565b61ffff16831792508160ff16600014610f7957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610f34565b50915091565b600080610fc28660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050610fdb866110fe565b84610fe687846117b3565b610ff091906117b3565b11156110035762ffffff19915050610708565b61100d85826117b3565b9050610bca8364ffffffffff168286610e53565b600061102d8260d81c90565b64ffffffffff1664ffffffffff0361104757506000919050565b6000611052836110fe565b60405110199392505050565b6060600061106b86610ebd565b915050600061107986610ebd565b915050600061108786610ebd565b915050600061109586610ebd565b915050838383836040516020016110af94939291906117cb565b604051602081830303815290604052945050505050949350505050565b60006110de60048360ff16901c611146565b60ff1661ffff919091161760081b6110f582611146565b60ff1617919050565b60006111188260181c6bffffffffffffffffffffffff1690565b6111308360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600060f08083179060ff821690036111615750603092915050565b8060ff1660f1036111755750603192915050565b8060ff1660f2036111895750603292915050565b8060ff1660f30361119d5750603392915050565b8060ff1660f4036111b15750603492915050565b8060ff1660f5036111c55750603592915050565b8060ff1660f6036111d95750603692915050565b8060ff1660f7036111ed5750603792915050565b8060ff1660f8036112015750603892915050565b8060ff1660f9036112155750603992915050565b8060ff1660fa036112295750606192915050565b8060ff1660fb0361123d5750606292915050565b8060ff1660fc036112515750606392915050565b8060ff1660fd036112655750606492915050565b8060ff1660fe036112795750606592915050565b8060ff1660ff036105645750606692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126112cd57600080fd5b813567ffffffffffffffff808211156112e8576112e861128d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561132e5761132e61128d565b8160405283815286602085880101111561134757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561137957600080fd5b813567ffffffffffffffff81111561139057600080fd5b610708848285016112bc565b60005b838110156113b757818101518382015260200161139f565b838111156113c6576000848401525b50505050565b600081518084526113e481602086016020860161139c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105d460208301846113cc565b803563ffffffff8116811461143d57600080fd5b919050565b600080600080600080600080610100898b03121561145f57600080fd5b61146889611429565b97506020890135965061147d60408a01611429565b955061148b60608a01611429565b9450608089013593506114a060a08a01611429565b925060c089013567ffffffffffffffff808211156114bd57600080fd5b6114c98c838d016112bc565b935060e08b01359150808211156114df57600080fd5b506114ec8b828c016112bc565b9150509295985092959890939650565b80356bffffffffffffffffffffffff8116811461143d57600080fd5b60008060008060008060008060008060006101608c8e03121561153a57600080fd5b6115438c611429565b9a5060208c0135995061155860408d01611429565b985061156660608d01611429565b975060808c0135965061157b60a08d01611429565b955061158960c08d016114fc565b945061159760e08d016114fc565b93506115a66101008d016114fc565b92506115b56101208d016114fc565b91506101408c013567ffffffffffffffff8111156115d257600080fd5b6115de8e828f016112bc565b9150509295989b509295989b9093969950565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff84168160ff048111821515161561167057611670611620565b029392505050565b600061ffff80831681851680830382111561169557611695611620565b01949350505050565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516116fe81600885016020890161139c565b84519083019061171581600884016020890161139c565b845191019061172b81600884016020880161139c565b016008019998505050505050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561177457611774611620565b500290565b60008282101561178b5761178b611620565b500390565b600060ff821660ff8416808210156117aa576117aa611620565b90039392505050565b600082198211156117c6576117c6611620565b500190565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201610bca56fea264697066735822122089be01887807d993be55d0deeea3e8d1eebb905286f817fbd90e73a773d2b05964736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c806381d030ef1161008c578063c97c703a11610066578063c97c703a146101de578063cb3eb0e1146101f1578063d7a7a72c14610204578063f45387ba1461021757600080fd5b806381d030ef146101a5578063985a5c31146101b8578063c81aa9c8146101cb57600080fd5b806352617f3c116100c857806352617f3c14610161578063639c5570146101775780636dc3c4f71461017f5780637c1cfff91461019257600080fd5b8063045c6c0b146100ef57806346fad66e146101185780634e76500414610139575b600080fd5b6101026100fd366004611367565b61024f565b60405161010f9190611416565b60405180910390f35b61012b610126366004611442565b61027c565b60405190815260200161010f565b61014c610147366004611367565b61032b565b60405163ffffffff909116815260200161010f565b60015b60405161ffff909116815260200161010f565b610164610352565b61012b61018d366004611367565b610368565b61014c6101a0366004611367565b610384565b6101026101b3366004611518565b6103a0565b61012b6101c6366004611367565b610477565b61014c6101d9366004611367565b610493565b6101026101ec366004611367565b6104af565b61014c6101ff366004611367565b6104cb565b61012b610212366004611367565b6104e7565b61022a610225366004611367565b610500565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010f565b606061027661026b6102608461051c565b62ffffff191661052a565b62ffffff191661056a565b92915050565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff0000000000000000000000000000000000000000000000000000000060e08b811b82166022840152602683018b905289811b8216604684015288811b8216604a840152604e830188905286901b16606e82015281518082036052018152607290910190915260009061031d8185856105bd565b9a9950505050505050505050565b600061027661034761033c8461051c565b62ffffff19166105db565b62ffffff1916610612565b60006103606004600261164f565b60ff16905090565b600061027661037961033c8461051c565b62ffffff191661063c565b600061027661039561033c8461051c565b62ffffff191661065d565b606060006103b08787878761067e565b905060006104588e8e8e8e8e8e604080517e01000000000000000000000000000000000000000000000000000000000000602082015260e097881b7fffffffff000000000000000000000000000000000000000000000000000000009081166022830152602682019790975294871b8616604686015292861b8516604a850152604e84019190915290931b909116606e82015281516052818303018152607290910190915290565b9050610465818386610710565b9e9d5050505050505050505050505050565b600061027661048861033c8461051c565b62ffffff191661078a565b60006102766104a461033c8461051c565b62ffffff19166107ab565b606061027661026b6104c08461051c565b62ffffff19166107cc565b60006102766104dc61033c8461051c565b62ffffff191661080b565b60006102766104f58361051c565b62ffffff191661082c565b600061027661051161033c8461051c565b62ffffff1916610851565b600061027682610539610862565b60008161053f62ffffff198216610539610886565b506105618361054f8560026109aa565b61055a8660036109aa565b60026109dc565b91505b50919050565b60606000806105878460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506105ac84836020016109fb565b508181016020016040529052919050565b60006105ca848484610710565b8051906020012090505b9392505050565b6000816105f062ffffff198216610539610886565b50610561836106008560016109aa565b61060b8660026109aa565b60016109dc565b60008161062860015b62ffffff19831690610886565b5061056162ffffff19841660266004610bd4565b600081610649600161061b565b5061056162ffffff19841660066020610c04565b60008161066a600161061b565b5061056162ffffff198416604e6004610bd4565b6040517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a086811b8216602284015285811b8216602e84015284811b8216603a84015283901b16604682015260609060520160405160208183030381529060405290505b949350505050565b82516060906000906107246004600261164f565b60ff166107319190611678565b905060008451826107429190611678565b905060016107526004600261164f565b60ff168383898989604051602001610770979695949392919061169e565b604051602081830303815290604052925050509392505050565b600081610797600161061b565b5061056162ffffff198416602e6020610c04565b6000816107b8600161061b565b5061056162ffffff198416602a6004610bd4565b6000816107e162ffffff198216610539610886565b50610561836107f18560036109aa565b601886901c6bffffffffffffffffffffffff1660036109dc565b600081610818600161061b565b5061056162ffffff19841660026004610bd4565b60008161084162ffffff198216610539610886565b5061056162ffffff198416610df6565b600061027661085f8361078a565b90565b81516000906020840161087d64ffffffffff85168284610e53565b95945050505050565b60006108928383610e9a565b6109a35760006108b16108a58560d81c90565b64ffffffffff16610ebd565b91505060006108c68464ffffffffff16610ebd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60405180910390fd5b5090919050565b60006105d460028360048111156109c3576109c36115f1565b6109cd919061173c565b62ffffff198516906002610bd4565b600061087d846109ec8186611779565b62ffffff198816919085610fa7565b600062ffffff1980841603610a92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161099a565b610a9b83611021565b610b27576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161099a565b6000610b418460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610b6b8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115610b905760206060fd5b8285848460045afa50610bca610ba68760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b6000610be1826020611790565b610bec90600861164f565b60ff16610bfa858585610c04565b901c949350505050565b60008160ff16600003610c19575060006105d4565b610c318460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c4c60ff8416856117b3565b1115610cde57610cab610c6d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16610c938660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661105e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099a9190611416565b60208260ff161115610d72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161099a565b600882026000610d908660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600080610e118360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000610e3b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080610e6083856117b3565b9050604051811115610e70575060005b80600003610e855762ffffff199150506105d4565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16610eae8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff161115610f30576000610edc82600861164f565b60ff1685901c9050610eed816110cc565b61ffff16841793508160ff16601014610f0857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610ec3565b50600f5b60ff8160ff161015610fa1576000610f4d82600861164f565b60ff1685901c9050610f5e816110cc565b61ffff16831792508160ff16600014610f7957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610f34565b50915091565b600080610fc28660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050610fdb866110fe565b84610fe687846117b3565b610ff091906117b3565b11156110035762ffffff19915050610708565b61100d85826117b3565b9050610bca8364ffffffffff168286610e53565b600061102d8260d81c90565b64ffffffffff1664ffffffffff0361104757506000919050565b6000611052836110fe565b60405110199392505050565b6060600061106b86610ebd565b915050600061107986610ebd565b915050600061108786610ebd565b915050600061109586610ebd565b915050838383836040516020016110af94939291906117cb565b604051602081830303815290604052945050505050949350505050565b60006110de60048360ff16901c611146565b60ff1661ffff919091161760081b6110f582611146565b60ff1617919050565b60006111188260181c6bffffffffffffffffffffffff1690565b6111308360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600060f08083179060ff821690036111615750603092915050565b8060ff1660f1036111755750603192915050565b8060ff1660f2036111895750603292915050565b8060ff1660f30361119d5750603392915050565b8060ff1660f4036111b15750603492915050565b8060ff1660f5036111c55750603592915050565b8060ff1660f6036111d95750603692915050565b8060ff1660f7036111ed5750603792915050565b8060ff1660f8036112015750603892915050565b8060ff1660f9036112155750603992915050565b8060ff1660fa036112295750606192915050565b8060ff1660fb0361123d5750606292915050565b8060ff1660fc036112515750606392915050565b8060ff1660fd036112655750606492915050565b8060ff1660fe036112795750606592915050565b8060ff1660ff036105645750606692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126112cd57600080fd5b813567ffffffffffffffff808211156112e8576112e861128d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561132e5761132e61128d565b8160405283815286602085880101111561134757600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561137957600080fd5b813567ffffffffffffffff81111561139057600080fd5b610708848285016112bc565b60005b838110156113b757818101518382015260200161139f565b838111156113c6576000848401525b50505050565b600081518084526113e481602086016020860161139c565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006105d460208301846113cc565b803563ffffffff8116811461143d57600080fd5b919050565b600080600080600080600080610100898b03121561145f57600080fd5b61146889611429565b97506020890135965061147d60408a01611429565b955061148b60608a01611429565b9450608089013593506114a060a08a01611429565b925060c089013567ffffffffffffffff808211156114bd57600080fd5b6114c98c838d016112bc565b935060e08b01359150808211156114df57600080fd5b506114ec8b828c016112bc565b9150509295985092959890939650565b80356bffffffffffffffffffffffff8116811461143d57600080fd5b60008060008060008060008060008060006101608c8e03121561153a57600080fd5b6115438c611429565b9a5060208c0135995061155860408d01611429565b985061156660608d01611429565b975060808c0135965061157b60a08d01611429565b955061158960c08d016114fc565b945061159760e08d016114fc565b93506115a66101008d016114fc565b92506115b56101208d016114fc565b91506101408c013567ffffffffffffffff8111156115d257600080fd5b6115de8e828f016112bc565b9150509295989b509295989b9093969950565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600060ff821660ff84168160ff048111821515161561167057611670611620565b029392505050565b600061ffff80831681851680830382111561169557611695611620565b01949350505050565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516116fe81600885016020890161139c565b84519083019061171581600884016020890161139c565b845191019061172b81600884016020880161139c565b016008019998505050505050505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561177457611774611620565b500290565b60008282101561178b5761178b611620565b500390565b600060ff821660ff8416808210156117aa576117aa611620565b90039392505050565b600082198211156117c6576117c6611620565b500190565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201610bca56fea264697066735822122089be01887807d993be55d0deeea3e8d1eebb905286f817fbd90e73a773d2b05964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44669:3643:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"44669:3643:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46655:135;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46100:549;;;;;;:::i;:::-;;:::i;:::-;;;3403:25:1;;;3391:2;3376:18;46100:549:0;3257:177:1;47218:132:0;;;;;;:::i;:::-;;:::i;:::-;;;3613:10:1;3601:23;;;3583:42;;3571:2;3556:18;47218:132:0;3439:192:1;48104:102:0;33745:1;48104:102;;;3810:6:1;3798:19;;;3780:38;;3768:2;3753:18;48104:102:0;3636:188:1;48212:98:0;;;:::i;47077:135::-;;;;;;:::i;:::-;;:::i;47814:156::-;;;;;;:::i;:::-;;:::i;44826:804::-;;;;;;:::i;:::-;;:::i;47506:141::-;;;;;;:::i;:::-;;:::i;47356:144::-;;;;;;:::i;:::-;;:::i;46796:135::-;;;;;;:::i;:::-;;:::i;46937:134::-;;;;;;:::i;:::-;;:::i;47976:122::-;;;;;;:::i;:::-;;:::i;47653:155::-;;;;;;:::i;:::-;;:::i;:::-;;;5236:42:1;5224:55;;;5206:74;;5194:2;5179:18;47653:155:0;5060:226:1;46655:135:0;46715:12;46746:37;:29;:22;:8;:20;:22::i;:::-;-1:-1:-1;;46746:27:0;;:29::i;:::-;-1:-1:-1;;46746:35:0;;:37::i;:::-;46739:44;46655:135;-1:-1:-1;;46655:135:0:o;46100:549::-;39644:242;;;6215:16:1;39644:242:0;;;6199:102:1;6320:66;6423:3;6419:16;;;6415:25;;6402:11;;;6395:46;6457:11;;;6450:27;;;6511:16;;;6507:25;;6493:12;;;6486:47;6567:16;;;6563:25;;6549:12;;;6542:47;6605:12;;;6598:28;;;6660:16;;;6656:25;6642:12;;;6635:47;39644:242:0;;;;;;;;;6698:12:1;;;;39644:242:0;;;46368:7;;46600:42;46620:7;46629:5;46636;46600:19;:42::i;:::-;46593:49;46100:549;-1:-1:-1;;;;;;;;;;46100:549:0:o;47218:132::-;47279:6;47304:39;:31;:22;:8;:20;:22::i;:::-;-1:-1:-1;;47304:29:0;;:31::i;:::-;-1:-1:-1;;47304:37:0;;:39::i;48212:98::-;48257:6;35024:29;35042:10;34895:1;35024:29;:::i;:::-;48282:21;;48275:28;;48212:98;:::o;47077:135::-;47139:7;47165:40;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47165:38:0;;:40::i;47814:156::-;47887:6;47912:51;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47912:49:0;;:51::i;44826:804::-;45223:12;45247:18;45268:68;45284:11;45297;45310:10;45322:13;45268:15;:68::i;:::-;45247:89;;45347:20;45370:185;45403:13;45430:7;45451:6;45471:18;45503:10;45527:18;39644:242;;;6215:16:1;39644:242:0;;;6199:102:1;6423:3;6419:16;;;6320:66;6415:25;;;6402:11;;;6395:46;6457:11;;;6450:27;;;;6511:16;;;6507:25;;6493:12;;;6486:47;6567:16;;;6563:25;;6549:12;;;6542:47;6605:12;;;6598:28;;;;6660:16;;;6656:25;;;6642:12;;;6635:47;39644:242:0;;;;;;;;;6698:12:1;;;;39644:242:0;;;;39374:519;45370:185;45347:208;;45572:51;45594:7;45603:5;45610:12;45572:21;:51::i;:::-;45565:58;44826:804;-1:-1:-1;;;;;;;;;;;;;;44826:804:0:o;47506:141::-;47571:7;47597:43;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47597:41:0;;:43::i;47356:144::-;47423:6;47448:45;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47448:43:0;;:45::i;46796:135::-;46856:12;46887:37;:29;:22;:8;:20;:22::i;:::-;-1:-1:-1;;46887:27:0;;:29::i;46937:134::-;46999:6;47024:40;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47024:38:0;;:40::i;47976:122::-;48036:7;48062:29;:22;:8;:20;:22::i;:::-;-1:-1:-1;;48062:27:0;;:29::i;47653:155::-;47725:7;47751:50;:31;:22;:8;:20;:22::i;:31::-;-1:-1:-1;;47751:48:0;;:50::i;36381:126::-;36448:7;36474:26;:8;33969:4;36474:12;:26::i;37058:299::-;37135:7;37116:8;34213:30;-1:-1:-1;;34213:16:0;;33969:4;34213:16;:30::i;:::-;;37173:177:::1;37199:8;37225:33;37237:8;37247:10;37225:11;:33::i;:::-;37276;37288:8;37298:10;37276:11;:33::i;:::-;34088:10;37173:8;:177::i;:::-;37154:196;;34253:1;37058:299:::0;;;;:::o;28308:632::-;28363:16;28391:11;28412:12;28427;28431:7;16492:2;16488:16;2670:26;16484:28;;16246:282;28427:12;28412:27;;;;28549:4;28543:11;28536:18;;28604:3;28597:10;;28650:33;28663:7;28672:3;28678:4;28672:10;28650:12;:33::i;:::-;-1:-1:-1;28807:14:0;;;28823:4;28803:25;28797:4;28790:39;28870:17;;28308:632;;-1:-1:-1;28308:632:0:o;36145:230::-;36288:7;36324:43;36338:7;36347:5;36354:12;36324:13;:43::i;:::-;36314:54;;;;;;36307:61;;36145:230;;;;;;:::o;36631:305::-;36710:7;36691:8;34213:30;-1:-1:-1;;34213:16:0;;33969:4;34213:16;:30::i;:::-;;36748:181:::1;36774:8;36800:35;36812:8;36822:12;36800:11;:35::i;:::-;36853:33;36865:8;36875:10;36853:11;:33::i;:::-;34025:12;37173:8;:177::i;40628:149::-:0;40703:6;40685:7;39313:37;34025:12;34018:20;-1:-1:-1;;39313:16:0;;;;:37::i;:::-;-1:-1:-1;40735:34:0::1;-1:-1:-1::0;;40735:17:0;::::1;39089:2;40767:1;40735:17;:34::i;40436:141::-:0;40512:7;40494;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;40538:32:0::1;-1:-1:-1::0;;40538:13:0;::::1;39041:1;40567:2;40538:13;:32::i;41272:174::-:0;41359:6;41341:7;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;41391:47:0::1;-1:-1:-1::0;;41391:17:0;::::1;39259:2;41436:1;41391:17;:47::i;42738:283::-:0;42931:83;;6968:16:1;42931:83:0;;;6952:102:1;7073:66;7176:3;7172:16;;;7168:25;;7155:11;;;7148:46;7228:16;;;7224:25;;7210:12;;;7203:47;7284:16;;;7280:25;;7266:12;;;7259:47;7340:16;;;7336:25;7322:12;;;7315:47;42900:12:0;;7378::1;;42931:83:0;;;;;;;;;;;;42924:90;;42738:283;;;;;;;:::o;35273:638::-;35569:14;;35418:12;;35526:17;;35024:29;35042:10;34895:1;35024:29;:::i;:::-;35546:13;;:38;;;;:::i;:::-;35526:58;;35594:17;35634:5;:12;35614:10;:33;;;;:::i;:::-;35594:53;-1:-1:-1;33745:1:0;35024:29;35042:10;34895:1;35024:29;:::i;:::-;35743:13;;35774:10;35802;35830:7;35855:5;35878:12;35676:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;35657:247;;;;35273:638;;;;;:::o;41061:147::-;41140:7;41122;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;41166:35:0::1;-1:-1:-1::0;;41166:13:0;::::1;39197:2;41198;41166:13;:35::i;40834:161::-:0;40915:6;40897:7;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;40947:40:0::1;-1:-1:-1::0;;40947:17:0;::::1;39144:2;40985:1;40947:17;:40::i;37479:190::-:0;37556:7;37537:8;34213:30;-1:-1:-1;;34213:16:0;;33969:4;34213:16;:30::i;:::-;;37582:80:::1;37591:8;37601:33;37613:8;37623:10;37601:11;:33::i;:::-;16492:2:::0;16488:16;;;2670:26;16484:28;34149:10:::1;37173:8;:177::i;40233:151::-:0;40309:6;40291:7;39313:37;34025:12;34018:20;;39313:37;-1:-1:-1;40341:35:0::1;-1:-1:-1::0;;40341:17:0;::::1;38992:1;40374;40341:17;:35::i;37730:170::-:0;37807:7;37788:8;34213:30;-1:-1:-1;;34213:16:0;;33969:4;34213:16;:30::i;:::-;-1:-1:-1;37876:17:0::1;-1:-1:-1::0;;37876:15:0;::::1;;:17::i;41515:145::-:0;41581:7;41607:46;41634:18;41644:7;41634:9;:18::i;:::-;33368:4;33255:127;13655:359;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;:::-;13974:33;13655:359;-1:-1:-1;;;;;13655:359:0:o;10073:578::-;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;9075:31:1;10385:186:0;;;9063:44:1;9126:66;9230:3;9226:16;;;9222:25;;9208:12;;;9201:47;9278:15;9264:12;;;9257:37;9328:16;;;9324:25;9310:12;;;9303:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;9366:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;;;;;;;;;;:::i;:::-;;;;;;;;10170:451;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;38191:164::-;38265:7;38291:57;34895:1;38318:5;38310:14;;;;;;;;:::i;:::-;:26;;;;:::i;:::-;-1:-1:-1;;38291:18:0;;;34895:1;38291:18;:57::i;37906:218::-;38047:7;38073:44;38088:5;38095:11;38088:5;38095:3;:11;:::i;:::-;-1:-1:-1;;38073:14:0;;;:44;38108:8;38073:14;:44::i;27036:902::-;27114:15;-1:-1:-1;;7972:15:0;;;;27141:69;;;;;;;10178:2:1;27141:69:0;;;10160:21:1;10217:2;10197:18;;;10190:30;10256:34;10236:18;;;10229:62;10327:10;10307:18;;;10300:38;10355:19;;27141:69:0;9976:404:1;27141:69:0;27228:16;27236:7;27228;:16::i;:::-;27220:72;;;;;;;10587:2:1;27220:72:0;;;10569:21:1;10626:2;10606:18;;;10599:30;10665:34;10645:18;;;10638:62;10736:13;10716:18;;;10709:41;10767:19;;27220:72:0;10385:407:1;27220:72:0;27302:12;27317;27321:7;16492:2;16488:16;2670:26;16484:28;;16246:282;27317:12;27302:27;;;;27339:15;27357:12;27361:7;15386:3;15382:17;2670:26;15378:29;;15059:364;27357:12;27339:30;;;;27380:11;27501:4;27495:11;27488:18;;27588:7;27583:3;27580:16;27577:94;;;27628:4;27622;27615:18;27577:94;27843:4;27834:7;27828:4;27819:7;27816:1;27809:5;27798:50;27794:55;27879:52;27900:15;27907:7;14417:3;14413:17;;14206:268;27900:15;12061:27;12065:2;12061:27;;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;;11811:446;27879:52;27869:62;27036:902;-1:-1:-1;;;;;;27036:902:0:o;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;;;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;;;;11332:2:1;20359:83:0;;;11314:21:1;11371:2;11351:18;;;11344:30;11410:34;11390:18;;;11383:62;11481:28;11461:18;;;11454:56;11527:19;;20359:83:0;11130:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;22455:290::-;22511:14;22537:12;22552;22556:7;15386:3;15382:17;2670:26;15378:29;;15059:364;22552:12;22537:27;;;;22574:12;22589;22593:7;16492:2;16488:16;2670:26;16484:28;;16246:282;22589:12;22574:27;;22708:21;;;;22455:290;-1:-1:-1;;;22455:290:0:o;12796:462::-;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;-1:-1:-1;;12065:2:0;12061:27;;;12135:17;;;;12127:26;;;12199:17;12195:2;12191:26;;12796:462::o;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;17129:399::-;17268:7;17287:12;17302;17306:7;15386:3;15382:17;2670:26;15378:29;;15059:364;17302:12;17287:27;;;;17398:12;17402:7;17398:3;:12::i;:::-;17391:4;17375:13;17382:6;17375:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17371:77;;;-1:-1:-1;;17426:11:0;;;;;17371:77;17465:13;17472:6;17465:4;:13;:::i;:::-;17458:20;;17495:26;17501:7;17495:26;;17510:4;17516;17495:5;:26::i;8645:333::-;8702:8;8726:15;8733:7;14417:3;14413:17;;14206:268;8726:15;:31;;8745:12;8726:31;8722:74;;-1:-1:-1;8780:5:0;;8645:333;-1:-1:-1;8645:333:0:o;8722:74::-;8805:12;8820;8824:7;8820:3;:12::i;:::-;8955:4;8949:11;-1:-1:-1;8936:26:0;;8645:333;-1:-1:-1;;;8645:333:0:o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19061:33;;;19244:1;19306;19386;19448;19130:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19104:391;;18926:576;;;;18761:741;;;;;;:::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;16702:147::-;16755:7;16820:12;16824:7;16492:2;16488:16;2670:26;16484:28;;16246:282;16820:12;16805;16809:7;15386:3;15382:17;2670:26;15378:29;;15059:364;16805:12;:27;16798:34;;;;16702:147;;;:::o;2943:1393::-;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;14:184:1:-;66:77;63:1;56:88;163:4;160:1;153:15;187:4;184:1;177:15;203:777;245:5;298:3;291:4;283:6;279:17;275:27;265:55;;316:1;313;306:12;265:55;352:6;339:20;378:18;415:2;411;408:10;405:36;;;421:18;;:::i;:::-;555:2;549:9;617:4;609:13;;460:66;605:22;;;629:2;601:31;597:40;585:53;;;653:18;;;673:22;;;650:46;647:72;;;699:18;;:::i;:::-;739:10;735:2;728:22;774:2;766:6;759:18;820:3;813:4;808:2;800:6;796:15;792:26;789:35;786:55;;;837:1;834;827:12;786:55;901:2;894:4;886:6;882:17;875:4;867:6;863:17;850:54;948:1;941:4;936:2;928:6;924:15;920:26;913:37;968:6;959:15;;;;;;203:777;;;;:::o;985:320::-;1053:6;1106:2;1094:9;1085:7;1081:23;1077:32;1074:52;;;1122:1;1119;1112:12;1074:52;1162:9;1149:23;1195:18;1187:6;1184:30;1181:50;;;1227:1;1224;1217:12;1181:50;1250:49;1291:7;1282:6;1271:9;1267:22;1250:49;:::i;1310:258::-;1382:1;1392:113;1406:6;1403:1;1400:13;1392:113;;;1482:11;;;1476:18;1463:11;;;1456:39;1428:2;1421:10;1392:113;;;1523:6;1520:1;1517:13;1514:48;;;1558:1;1549:6;1544:3;1540:16;1533:27;1514:48;;1310:258;;;:::o;1573:316::-;1614:3;1652:5;1646:12;1679:6;1674:3;1667:19;1695:63;1751:6;1744:4;1739:3;1735:14;1728:4;1721:5;1717:16;1695:63;:::i;:::-;1803:2;1791:15;1808:66;1787:88;1778:98;;;;1878:4;1774:109;;1573:316;-1:-1:-1;;1573:316:1:o;1894:217::-;2041:2;2030:9;2023:21;2004:4;2061:44;2101:2;2090:9;2086:18;2078:6;2061:44;:::i;2116:163::-;2183:20;;2243:10;2232:22;;2222:33;;2212:61;;2269:1;2266;2259:12;2212:61;2116:163;;;:::o;2284:968::-;2420:6;2428;2436;2444;2452;2460;2468;2476;2529:3;2517:9;2508:7;2504:23;2500:33;2497:53;;;2546:1;2543;2536:12;2497:53;2569:28;2587:9;2569:28;:::i;:::-;2559:38;;2644:2;2633:9;2629:18;2616:32;2606:42;;2667:37;2700:2;2689:9;2685:18;2667:37;:::i;:::-;2657:47;;2723:37;2756:2;2745:9;2741:18;2723:37;:::i;:::-;2713:47;;2807:3;2796:9;2792:19;2779:33;2769:43;;2831:38;2864:3;2853:9;2849:19;2831:38;:::i;:::-;2821:48;;2920:3;2909:9;2905:19;2892:33;2944:18;2985:2;2977:6;2974:14;2971:34;;;3001:1;2998;2991:12;2971:34;3024:49;3065:7;3056:6;3045:9;3041:22;3024:49;:::i;:::-;3014:59;;3126:3;3115:9;3111:19;3098:33;3082:49;;3156:2;3146:8;3143:16;3140:36;;;3172:1;3169;3162:12;3140:36;;3195:51;3238:7;3227:8;3216:9;3212:24;3195:51;:::i;:::-;3185:61;;;2284:968;;;;;;;;;;;:::o;3829:179::-;3896:20;;3956:26;3945:38;;3935:49;;3925:77;;3998:1;3995;3988:12;4013:1042;4163:6;4171;4179;4187;4195;4203;4211;4219;4227;4235;4243:7;4297:3;4285:9;4276:7;4272:23;4268:33;4265:53;;;4314:1;4311;4304:12;4265:53;4337:28;4355:9;4337:28;:::i;:::-;4327:38;;4412:2;4401:9;4397:18;4384:32;4374:42;;4435:37;4468:2;4457:9;4453:18;4435:37;:::i;:::-;4425:47;;4491:37;4524:2;4513:9;4509:18;4491:37;:::i;:::-;4481:47;;4575:3;4564:9;4560:19;4547:33;4537:43;;4599:38;4632:3;4621:9;4617:19;4599:38;:::i;:::-;4589:48;;4656:38;4689:3;4678:9;4674:19;4656:38;:::i;:::-;4646:48;;4713:38;4746:3;4735:9;4731:19;4713:38;:::i;:::-;4703:48;;4770:38;4803:3;4792:9;4788:19;4770:38;:::i;:::-;4760:48;;4827:38;4860:3;4849:9;4845:19;4827:38;:::i;:::-;4817:48;;4916:3;4905:9;4901:19;4888:33;4944:18;4936:6;4933:30;4930:50;;;4976:1;4973;4966:12;4930:50;5000:49;5041:7;5032:6;5021:9;5017:22;5000:49;:::i;:::-;4989:60;;;4013:1042;;;;;;;;;;;;;;:::o;5291:184::-;5343:77;5340:1;5333:88;5440:4;5437:1;5430:15;5464:4;5461:1;5454:15;5480:184;5532:77;5529:1;5522:88;5629:4;5626:1;5619:15;5653:4;5650:1;5643:15;5669:238;5707:7;5747:4;5744:1;5740:12;5779:4;5776:1;5772:12;5839:3;5833:4;5829:14;5824:3;5821:23;5814:3;5807:11;5800:19;5796:49;5793:75;;;5848:18;;:::i;:::-;5888:13;;5669:238;-1:-1:-1;;;5669:238:1:o;7401:224::-;7440:3;7468:6;7501:2;7498:1;7494:10;7531:2;7528:1;7524:10;7562:3;7558:2;7554:12;7549:3;7546:21;7543:47;;;7570:18;;:::i;:::-;7606:13;;7401:224;-1:-1:-1;;;;7401:224:1:o;7630:1073::-;7955:3;7983:66;8092:2;8083:6;8078:3;8074:16;8070:25;8065:3;8058:38;8147:2;8138:6;8133:3;8129:16;8125:25;8121:1;8116:3;8112:11;8105:46;8202:2;8193:6;8188:3;8184:16;8180:25;8176:1;8171:3;8167:11;8160:46;8257:2;8248:6;8243:3;8239:16;8235:25;8231:1;8226:3;8222:11;8215:46;;8290:6;8284:13;8306:61;8360:6;8356:1;8351:3;8347:11;8340:4;8332:6;8328:17;8306:61;:::i;:::-;8427:13;;8386:16;;;;8449:62;8427:13;8498:1;8490:10;;8483:4;8471:17;;8449:62;:::i;:::-;8572:13;;8530:17;;;8594:62;8572:13;8643:1;8635:10;;8628:4;8616:17;;8594:62;:::i;:::-;8676:17;8695:1;8672:25;;7630:1073;-1:-1:-1;;;;;;;;;7630:1073:1:o;9613:228::-;9653:7;9779:1;9711:66;9707:74;9704:1;9701:81;9696:1;9689:9;9682:17;9678:105;9675:131;;;9786:18;;:::i;:::-;-1:-1:-1;9826:9:1;;9613:228::o;9846:125::-;9886:4;9914:1;9911;9908:8;9905:34;;;9919:18;;:::i;:::-;-1:-1:-1;9956:9:1;;9846:125::o;10797:195::-;10835:4;10872;10869:1;10865:12;10904:4;10901:1;10897:12;10929:3;10924;10921:12;10918:38;;;10936:18;;:::i;:::-;10973:13;;;10797:195;-1:-1:-1;;;10797:195:1:o;10997:128::-;11037:3;11068:1;11064:6;11061:1;11058:13;11055:39;;;11074:18;;:::i;:::-;-1:-1:-1;11110:9:1;;10997:128::o;11676:1391::-;12398:34;12386:47;;12463:23;12458:2;12449:12;;12442:45;12506:66;12610:3;12606:16;;;12602:25;;12597:2;12588:12;;12581:47;12647:17;12689:2;12680:12;;12673:24;;;12731:16;;;12727:25;;12722:2;12713:12;;12706:47;12783:34;12778:2;12769:12;;12762:56;12849:3;12843;12834:13;;12827:26;12888:16;;;12884:25;;12878:3;12869:13;;12862:48;12935:3;12926:13;;12919:25;12979:16;;;12975:25;12969:3;12960:13;;12953:48;11634:3;13056;13047:13;;11622:16;-1:-1:-1;11654:11:1;;;13017:44;11557:114","abiDefinition":[{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"body","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"destination","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_originDomain","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"uint96","name":"_updaterTip","type":"uint96"},{"internalType":"uint96","name":"_relayerTip","type":"uint96"},{"internalType":"uint96","name":"_proverTip","type":"uint96"},{"internalType":"uint96","name":"_processorTip","type":"uint96"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"formatMessage","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"headerOffset","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"leaf","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"_origin","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"uint32","name":"_destination","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_body","type":"bytes"}],"name":"messageHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"messageVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"optimisticSeconds","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"origin","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"recipient","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"recipientAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"sender","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"tips","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{"messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)":{"notice":"Returns leaf of formatted message with provided fields."}},"version":1},"developerDoc":{"kind":"dev","methods":{"messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)":{"params":{"_body":"Raw bytes of message body","_destination":"Domain of destination chain","_nonce":"Destination-specific nonce number","_origin":"Domain of home chain","_recipient":"Address of recipient on destination chain as bytes32","_sender":"Address of sender as bytes32"},"returns":{"_0":"Leaf (hash) of formatted message*"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"body\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"destination\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_originDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipient\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"_updaterTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_relayerTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_proverTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_processorTip\",\"type\":\"uint96\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"formatMessage\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"headerOffset\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"leaf\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_destination\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipient\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_body\",\"type\":\"bytes\"}],\"name\":\"messageHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"messageVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"optimisticSeconds\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"origin\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"recipient\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"recipientAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"sender\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"tips\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)\":{\"params\":{\"_body\":\"Raw bytes of message body\",\"_destination\":\"Domain of destination chain\",\"_nonce\":\"Destination-specific nonce number\",\"_origin\":\"Domain of home chain\",\"_recipient\":\"Address of recipient on destination chain as bytes32\",\"_sender\":\"Address of sender as bytes32\"},\"returns\":{\"_0\":\"Leaf (hash) of formatted message*\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Returns leaf of formatted message with provided fields.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"MessageHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0x9a175023e8877c248b3f22cf08da899c122f6c8a5035509de971715be1c01547\",\"urls\":[\"bzz-raw://aa51718c01e07a0176734750853816ff2d24b343c60af773db6d51d7b0f62f3e\",\"dweb:/ipfs/QmW5EWU8AcHm9SeEPiijmHonWuau17KFmuFD53hftknuGc\"]}},\"version\":1}"},"hashes":{"body(bytes)":"c97c703a","destination(bytes)":"c81aa9c8","formatMessage(uint32,bytes32,uint32,uint32,bytes32,uint32,uint96,uint96,uint96,uint96,bytes)":"81d030ef","headerOffset()":"639c5570","leaf(bytes)":"d7a7a72c","messageHash(uint32,bytes32,uint32,uint32,bytes32,uint32,bytes,bytes)":"46fad66e","messageVersion()":"52617f3c","nonce(bytes)":"4e765004","optimisticSeconds(bytes)":"7c1cfff9","origin(bytes)":"cb3eb0e1","recipient(bytes)":"985a5c31","recipientAddress(bytes)":"f45387ba","sender(bytes)":"6dc3c4f7","tips(bytes)":"045c6c0b"}},"solidity/MessageHarness.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f3469144348bb87fd91eb6075375c413450f79177a79df3df4f532c0d2d9814364736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f3469144348bb87fd91eb6075375c413450f79177a79df3df4f532c0d2d9814364736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"41664:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;41664:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"41664:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0x9a175023e8877c248b3f22cf08da899c122f6c8a5035509de971715be1c01547\",\"urls\":[\"bzz-raw://aa51718c01e07a0176734750853816ff2d24b343c60af773db6d51d7b0f62f3e\",\"dweb:/ipfs/QmW5EWU8AcHm9SeEPiijmHonWuau17KFmuFD53hftknuGc\"]}},\"version\":1}"},"hashes":{}},"solidity/MessageHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122069b7b1b9a024871cfa8ccbdcfa6d301f5e627bc40a3d10b688ca869fe49b1e4164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122069b7b1b9a024871cfa8ccbdcfa6d301f5e627bc40a3d10b688ca869fe49b1e4164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32274:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32274:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32274:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0x9a175023e8877c248b3f22cf08da899c122f6c8a5035509de971715be1c01547\",\"urls\":[\"bzz-raw://aa51718c01e07a0176734750853816ff2d24b343c60af773db6d51d7b0f62f3e\",\"dweb:/ipfs/QmW5EWU8AcHm9SeEPiijmHonWuau17KFmuFD53hftknuGc\"]}},\"version\":1}"},"hashes":{}},"solidity/MessageHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122065d18d890d97379832d683ea0feb3baaba8ee9eab100fd3c386e477863365a6a64736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122065d18d890d97379832d683ea0feb3baaba8ee9eab100fd3c386e477863365a6a64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \ncontract MessageHarness {\n using Message for bytes;\n using Message for bytes29;\n using Header for bytes29;\n using TypedMemView for bytes29;\n\n function formatMessage(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n // tips params\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip,\n bytes memory _messageBody\n ) public pure returns (bytes memory) {\n bytes memory _tips = Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n\n bytes memory _header = Header.formatHeader(\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n return Message.formatMessage(_header, _tips, _messageBody);\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _origin Domain of home chain\n * @param _sender Address of sender as bytes32\n * @param _nonce Destination-specific nonce number\n * @param _destination Domain of destination chain\n * @param _recipient Address of recipient on destination chain as bytes32\n * @param _body Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n uint32 _origin,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destination,\n bytes32 _recipient,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _body\n ) public pure returns (bytes32) {\n bytes memory _header = Header.formatHeader(\n _origin,\n _sender,\n _nonce,\n _destination,\n _recipient,\n _optimisticSeconds\n );\n return Message.messageHash(_header, _tips, _body);\n }\n\n function tips(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().tips().clone();\n }\n\n function body(bytes memory _message) external view returns (bytes memory) {\n return _message.messageView().body().clone();\n }\n\n function origin(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().origin();\n }\n\n function sender(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().sender();\n }\n\n function nonce(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().nonce();\n }\n\n function destination(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().destination();\n }\n\n function recipient(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().header().recipient();\n }\n\n function recipientAddress(bytes memory _message) external pure returns (address) {\n return _message.messageView().header().recipientAddress();\n }\n\n function optimisticSeconds(bytes memory _message) external pure returns (uint32) {\n return _message.messageView().header().optimisticSeconds();\n }\n\n function leaf(bytes memory _message) external pure returns (bytes32) {\n return _message.messageView().leaf();\n }\n\n function messageVersion() public pure returns (uint16) {\n return Message.MESSAGE_VERSION;\n }\n\n function headerOffset() public pure returns (uint16) {\n return Message.HEADER_OFFSET;\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/MessageHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/MessageHarness.sol\":{\"keccak256\":\"0x9a175023e8877c248b3f22cf08da899c122f6c8a5035509de971715be1c01547\",\"urls\":[\"bzz-raw://aa51718c01e07a0176734750853816ff2d24b343c60af773db6d51d7b0f62f3e\",\"dweb:/ipfs/QmW5EWU8AcHm9SeEPiijmHonWuau17KFmuFD53hftknuGc\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}}} \ No newline at end of file diff --git a/core/contracts/test/replicamanagerharness/replicamanagerharness.abigen.go b/core/contracts/test/replicamanagerharness/replicamanagerharness.abigen.go index e843099fb2..43af36c683 100644 --- a/core/contracts/test/replicamanagerharness/replicamanagerharness.abigen.go +++ b/core/contracts/test/replicamanagerharness/replicamanagerharness.abigen.go @@ -28,10 +28,312 @@ var ( _ = event.NewSubscription ) +// AbstractGuardRegistryMetaData contains all meta data concerning the AbstractGuardRegistry contract. +var AbstractGuardRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractGuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractGuardRegistryMetaData.ABI instead. +var AbstractGuardRegistryABI = AbstractGuardRegistryMetaData.ABI + +// AbstractGuardRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractGuardRegistry struct { + AbstractGuardRegistryCaller // Read-only binding to the contract + AbstractGuardRegistryTransactor // Write-only binding to the contract + AbstractGuardRegistryFilterer // Log filterer for contract events +} + +// AbstractGuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractGuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractGuardRegistrySession struct { + Contract *AbstractGuardRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractGuardRegistryCallerSession struct { + Contract *AbstractGuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractGuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractGuardRegistryTransactorSession struct { + Contract *AbstractGuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractGuardRegistryRaw struct { + Contract *AbstractGuardRegistry // Generic contract binding to access the raw methods on +} + +// AbstractGuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCallerRaw struct { + Contract *AbstractGuardRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractGuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactorRaw struct { + Contract *AbstractGuardRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractGuardRegistry creates a new instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistry(address common.Address, backend bind.ContractBackend) (*AbstractGuardRegistry, error) { + contract, err := bindAbstractGuardRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractGuardRegistry{AbstractGuardRegistryCaller: AbstractGuardRegistryCaller{contract: contract}, AbstractGuardRegistryTransactor: AbstractGuardRegistryTransactor{contract: contract}, AbstractGuardRegistryFilterer: AbstractGuardRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractGuardRegistryCaller creates a new read-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractGuardRegistryCaller, error) { + contract, err := bindAbstractGuardRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryCaller{contract: contract}, nil +} + +// NewAbstractGuardRegistryTransactor creates a new write-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractGuardRegistryTransactor, error) { + contract, err := bindAbstractGuardRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryTransactor{contract: contract}, nil +} + +// NewAbstractGuardRegistryFilterer creates a new log filterer instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractGuardRegistryFilterer, error) { + contract, err := bindAbstractGuardRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryFilterer{contract: contract}, nil +} + +// bindAbstractGuardRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractGuardRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transact(opts, method, params...) +} + +// AbstractNotaryRegistryMetaData contains all meta data concerning the AbstractNotaryRegistry contract. +var AbstractNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractNotaryRegistryMetaData.ABI instead. +var AbstractNotaryRegistryABI = AbstractNotaryRegistryMetaData.ABI + +// AbstractNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractNotaryRegistry struct { + AbstractNotaryRegistryCaller // Read-only binding to the contract + AbstractNotaryRegistryTransactor // Write-only binding to the contract + AbstractNotaryRegistryFilterer // Log filterer for contract events +} + +// AbstractNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractNotaryRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractNotaryRegistrySession struct { + Contract *AbstractNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractNotaryRegistryCallerSession struct { + Contract *AbstractNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractNotaryRegistryTransactorSession struct { + Contract *AbstractNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractNotaryRegistryRaw struct { + Contract *AbstractNotaryRegistry // Generic contract binding to access the raw methods on +} + +// AbstractNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCallerRaw struct { + Contract *AbstractNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactorRaw struct { + Contract *AbstractNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractNotaryRegistry creates a new instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistry(address common.Address, backend bind.ContractBackend) (*AbstractNotaryRegistry, error) { + contract, err := bindAbstractNotaryRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistry{AbstractNotaryRegistryCaller: AbstractNotaryRegistryCaller{contract: contract}, AbstractNotaryRegistryTransactor: AbstractNotaryRegistryTransactor{contract: contract}, AbstractNotaryRegistryFilterer: AbstractNotaryRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractNotaryRegistryCaller creates a new read-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractNotaryRegistryCaller, error) { + contract, err := bindAbstractNotaryRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryCaller{contract: contract}, nil +} + +// NewAbstractNotaryRegistryTransactor creates a new write-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractNotaryRegistryTransactor, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryTransactor{contract: contract}, nil +} + +// NewAbstractNotaryRegistryFilterer creates a new log filterer instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractNotaryRegistryFilterer, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryFilterer{contract: contract}, nil +} + +// bindAbstractNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractNotaryRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transact(opts, method, params...) +} + // AddressUpgradeableMetaData contains all meta data concerning the AddressUpgradeable contract. var AddressUpgradeableMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122045f0ae72f6972f055d340df15ade41248d41b45df67b4ec5832c90c32e45746a64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d25c14d60f8a9c2700c5a064a16ba5c6887c5014073a19c8ecb828328ac95e0b64736f6c634300080d0033", } // AddressUpgradeableABI is the input ABI used to generate the binding from. @@ -204,7 +506,7 @@ func (_AddressUpgradeable *AddressUpgradeableTransactorRaw) Transact(opts *bind. // AttestationMetaData contains all meta data concerning the Attestation contract. var AttestationMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220138db4ec2682473b246847e5221eda76b4e56ce3165ba51993f0e5496b7962e764736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207c0dbe30d886cdc4b151bc64bfdcedad06581277216b34c43a192ab1b618c8eb64736f6c634300080d0033", } // AttestationABI is the input ABI used to generate the binding from. @@ -377,7 +679,7 @@ func (_Attestation *AttestationTransactorRaw) Transact(opts *bind.TransactOpts, // AuthMetaData contains all meta data concerning the Auth contract. var AuthMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b064a8ed2d124863495c5c80afc0eefe0b268aac8d265ccaafc03ff490c5562164736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204ac565f954e44279ccec9766349f01578ebcbb872f6ceaf531135398705bea0b64736f6c634300080d0033", } // AuthABI is the input ABI used to generate the binding from. @@ -547,157 +849,6 @@ func (_Auth *AuthTransactorRaw) Transact(opts *bind.TransactOpts, method string, return _Auth.Contract.contract.Transact(opts, method, params...) } -// AuthManagerMetaData contains all meta data concerning the AuthManager contract. -var AuthManagerMetaData = &bind.MetaData{ - ABI: "[]", -} - -// AuthManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use AuthManagerMetaData.ABI instead. -var AuthManagerABI = AuthManagerMetaData.ABI - -// AuthManager is an auto generated Go binding around an Ethereum contract. -type AuthManager struct { - AuthManagerCaller // Read-only binding to the contract - AuthManagerTransactor // Write-only binding to the contract - AuthManagerFilterer // Log filterer for contract events -} - -// AuthManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type AuthManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type AuthManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type AuthManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type AuthManagerSession struct { - Contract *AuthManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type AuthManagerCallerSession struct { - Contract *AuthManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// AuthManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type AuthManagerTransactorSession struct { - Contract *AuthManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type AuthManagerRaw struct { - Contract *AuthManager // Generic contract binding to access the raw methods on -} - -// AuthManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type AuthManagerCallerRaw struct { - Contract *AuthManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// AuthManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type AuthManagerTransactorRaw struct { - Contract *AuthManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewAuthManager creates a new instance of AuthManager, bound to a specific deployed contract. -func NewAuthManager(address common.Address, backend bind.ContractBackend) (*AuthManager, error) { - contract, err := bindAuthManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &AuthManager{AuthManagerCaller: AuthManagerCaller{contract: contract}, AuthManagerTransactor: AuthManagerTransactor{contract: contract}, AuthManagerFilterer: AuthManagerFilterer{contract: contract}}, nil -} - -// NewAuthManagerCaller creates a new read-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerCaller(address common.Address, caller bind.ContractCaller) (*AuthManagerCaller, error) { - contract, err := bindAuthManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &AuthManagerCaller{contract: contract}, nil -} - -// NewAuthManagerTransactor creates a new write-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*AuthManagerTransactor, error) { - contract, err := bindAuthManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &AuthManagerTransactor{contract: contract}, nil -} - -// NewAuthManagerFilterer creates a new log filterer instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*AuthManagerFilterer, error) { - contract, err := bindAuthManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &AuthManagerFilterer{contract: contract}, nil -} - -// bindAuthManager binds a generic wrapper to an already deployed contract. -func bindAuthManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(AuthManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.AuthManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transact(opts, method, params...) -} - // ContextUpgradeableMetaData contains all meta data concerning the ContextUpgradeable contract. var ContextUpgradeableMetaData = &bind.MetaData{ ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", @@ -986,7 +1137,7 @@ func (_ContextUpgradeable *ContextUpgradeableFilterer) ParseInitialized(log type // ECDSAMetaData contains all meta data concerning the ECDSA contract. var ECDSAMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122050e91500f11e5e06dfc508414913cc284ef67d1cc354481005cd9a7a3f59e8f864736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c3d9bb4f6efabc99aff44b49f45c704f844c7519adf9d31de8ba78cd5cb8694364736f6c634300080d0033", } // ECDSAABI is the input ABI used to generate the binding from. @@ -1156,23 +1307,23 @@ func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method strin return _ECDSA.Contract.contract.Transact(opts, method, params...) } -// HeaderMetaData contains all meta data concerning the Header contract. -var HeaderMetaData = &bind.MetaData{ +// EnumerableSetMetaData contains all meta data concerning the EnumerableSet contract. +var EnumerableSetMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e05411f0755cdc8f7a04b0971fb0613ef48b966a9285302b46caef9815783aaa64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e19ec396e6784a3ba231c4b74603e72835301c39327be67face151917bc1274d64736f6c634300080d0033", } -// HeaderABI is the input ABI used to generate the binding from. -// Deprecated: Use HeaderMetaData.ABI instead. -var HeaderABI = HeaderMetaData.ABI +// EnumerableSetABI is the input ABI used to generate the binding from. +// Deprecated: Use EnumerableSetMetaData.ABI instead. +var EnumerableSetABI = EnumerableSetMetaData.ABI -// HeaderBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HeaderMetaData.Bin instead. -var HeaderBin = HeaderMetaData.Bin +// EnumerableSetBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use EnumerableSetMetaData.Bin instead. +var EnumerableSetBin = EnumerableSetMetaData.Bin -// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. -func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { - parsed, err := HeaderMetaData.GetAbi() +// DeployEnumerableSet deploys a new Ethereum contract, binding an instance of EnumerableSet to it. +func DeployEnumerableSet(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *EnumerableSet, error) { + parsed, err := EnumerableSetMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1180,111 +1331,111 @@ func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EnumerableSetBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil + return address, tx, &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// Header is an auto generated Go binding around an Ethereum contract. -type Header struct { - HeaderCaller // Read-only binding to the contract - HeaderTransactor // Write-only binding to the contract - HeaderFilterer // Log filterer for contract events +// EnumerableSet is an auto generated Go binding around an Ethereum contract. +type EnumerableSet struct { + EnumerableSetCaller // Read-only binding to the contract + EnumerableSetTransactor // Write-only binding to the contract + EnumerableSetFilterer // Log filterer for contract events } -// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. -type HeaderCaller struct { +// EnumerableSetCaller is an auto generated read-only Go binding around an Ethereum contract. +type EnumerableSetCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HeaderTransactor struct { +// EnumerableSetTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EnumerableSetTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HeaderFilterer struct { +// EnumerableSetFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EnumerableSetFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderSession is an auto generated Go binding around an Ethereum contract, +// EnumerableSetSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type HeaderSession struct { - Contract *Header // Generic contract binding to set the session for +type EnumerableSetSession struct { + Contract *EnumerableSet // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// EnumerableSetCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type HeaderCallerSession struct { - Contract *HeaderCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type EnumerableSetCallerSession struct { + Contract *EnumerableSetCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// EnumerableSetTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type HeaderTransactorSession struct { - Contract *HeaderTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type EnumerableSetTransactorSession struct { + Contract *EnumerableSetTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. -type HeaderRaw struct { - Contract *Header // Generic contract binding to access the raw methods on +// EnumerableSetRaw is an auto generated low-level Go binding around an Ethereum contract. +type EnumerableSetRaw struct { + Contract *EnumerableSet // Generic contract binding to access the raw methods on } -// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HeaderCallerRaw struct { - Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on +// EnumerableSetCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EnumerableSetCallerRaw struct { + Contract *EnumerableSetCaller // Generic read-only contract binding to access the raw methods on } -// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HeaderTransactorRaw struct { - Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on +// EnumerableSetTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EnumerableSetTransactorRaw struct { + Contract *EnumerableSetTransactor // Generic write-only contract binding to access the raw methods on } -// NewHeader creates a new instance of Header, bound to a specific deployed contract. -func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { - contract, err := bindHeader(address, backend, backend, backend) +// NewEnumerableSet creates a new instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSet(address common.Address, backend bind.ContractBackend) (*EnumerableSet, error) { + contract, err := bindEnumerableSet(address, backend, backend, backend) if err != nil { return nil, err } - return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil + return &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. -func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { - contract, err := bindHeader(address, caller, nil, nil) +// NewEnumerableSetCaller creates a new read-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetCaller(address common.Address, caller bind.ContractCaller) (*EnumerableSetCaller, error) { + contract, err := bindEnumerableSet(address, caller, nil, nil) if err != nil { return nil, err } - return &HeaderCaller{contract: contract}, nil + return &EnumerableSetCaller{contract: contract}, nil } -// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. -func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { - contract, err := bindHeader(address, nil, transactor, nil) +// NewEnumerableSetTransactor creates a new write-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetTransactor(address common.Address, transactor bind.ContractTransactor) (*EnumerableSetTransactor, error) { + contract, err := bindEnumerableSet(address, nil, transactor, nil) if err != nil { return nil, err } - return &HeaderTransactor{contract: contract}, nil + return &EnumerableSetTransactor{contract: contract}, nil } -// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. -func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { - contract, err := bindHeader(address, nil, nil, filterer) +// NewEnumerableSetFilterer creates a new log filterer instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetFilterer(address common.Address, filterer bind.ContractFilterer) (*EnumerableSetFilterer, error) { + contract, err := bindEnumerableSet(address, nil, nil, filterer) if err != nil { return nil, err } - return &HeaderFilterer{contract: contract}, nil + return &EnumerableSetFilterer{contract: contract}, nil } -// bindHeader binds a generic wrapper to an already deployed contract. -func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HeaderABI)) +// bindEnumerableSet binds a generic wrapper to an already deployed contract. +func bindEnumerableSet(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(EnumerableSetABI)) if err != nil { return nil, err } @@ -1295,154 +1446,169 @@ func bindHeader(address common.Address, caller bind.ContractCaller, transactor b // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) +func (_EnumerableSet *EnumerableSetRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.EnumerableSetCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transfer(opts) +func (_EnumerableSet *EnumerableSetRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) +func (_EnumerableSet *EnumerableSetRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.contract.Call(opts, result, method, params...) +func (_EnumerableSet *EnumerableSetCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.contract.Transfer(opts) +func (_EnumerableSet *EnumerableSetTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.contract.Transact(opts, method, params...) +func (_EnumerableSet *EnumerableSetTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transact(opts, method, params...) } -// IMessageRecipientMetaData contains all meta data concerning the IMessageRecipient contract. -var IMessageRecipientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_rootTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"handle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "e4d16d62": "handle(uint32,uint32,bytes32,uint256,bytes)", - }, +// GlobalNotaryRegistryMetaData contains all meta data concerning the GlobalNotaryRegistry contract. +var GlobalNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"}]", + Bin: "0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea26469706673582212202c863d08bbc429683a33ede55c774990b476fb8c04c443ed799eb51db38eac6764736f6c634300080d0033", } -// IMessageRecipientABI is the input ABI used to generate the binding from. -// Deprecated: Use IMessageRecipientMetaData.ABI instead. -var IMessageRecipientABI = IMessageRecipientMetaData.ABI +// GlobalNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use GlobalNotaryRegistryMetaData.ABI instead. +var GlobalNotaryRegistryABI = GlobalNotaryRegistryMetaData.ABI -// Deprecated: Use IMessageRecipientMetaData.Sigs instead. -// IMessageRecipientFuncSigs maps the 4-byte function signature to its string representation. -var IMessageRecipientFuncSigs = IMessageRecipientMetaData.Sigs +// GlobalNotaryRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GlobalNotaryRegistryMetaData.Bin instead. +var GlobalNotaryRegistryBin = GlobalNotaryRegistryMetaData.Bin -// IMessageRecipient is an auto generated Go binding around an Ethereum contract. -type IMessageRecipient struct { - IMessageRecipientCaller // Read-only binding to the contract - IMessageRecipientTransactor // Write-only binding to the contract - IMessageRecipientFilterer // Log filterer for contract events +// DeployGlobalNotaryRegistry deploys a new Ethereum contract, binding an instance of GlobalNotaryRegistry to it. +func DeployGlobalNotaryRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GlobalNotaryRegistry, error) { + parsed, err := GlobalNotaryRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GlobalNotaryRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GlobalNotaryRegistry{GlobalNotaryRegistryCaller: GlobalNotaryRegistryCaller{contract: contract}, GlobalNotaryRegistryTransactor: GlobalNotaryRegistryTransactor{contract: contract}, GlobalNotaryRegistryFilterer: GlobalNotaryRegistryFilterer{contract: contract}}, nil } -// IMessageRecipientCaller is an auto generated read-only Go binding around an Ethereum contract. -type IMessageRecipientCaller struct { +// GlobalNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type GlobalNotaryRegistry struct { + GlobalNotaryRegistryCaller // Read-only binding to the contract + GlobalNotaryRegistryTransactor // Write-only binding to the contract + GlobalNotaryRegistryFilterer // Log filterer for contract events +} + +// GlobalNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// IMessageRecipientTransactor is an auto generated write-only Go binding around an Ethereum contract. -type IMessageRecipientTransactor struct { +// GlobalNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// IMessageRecipientFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type IMessageRecipientFilterer struct { +// GlobalNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GlobalNotaryRegistryFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// IMessageRecipientSession is an auto generated Go binding around an Ethereum contract, +// GlobalNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type IMessageRecipientSession struct { - Contract *IMessageRecipient // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type GlobalNotaryRegistrySession struct { + Contract *GlobalNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// IMessageRecipientCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// GlobalNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type IMessageRecipientCallerSession struct { - Contract *IMessageRecipientCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type GlobalNotaryRegistryCallerSession struct { + Contract *GlobalNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// IMessageRecipientTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// GlobalNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type IMessageRecipientTransactorSession struct { - Contract *IMessageRecipientTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type GlobalNotaryRegistryTransactorSession struct { + Contract *GlobalNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// IMessageRecipientRaw is an auto generated low-level Go binding around an Ethereum contract. -type IMessageRecipientRaw struct { - Contract *IMessageRecipient // Generic contract binding to access the raw methods on +// GlobalNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type GlobalNotaryRegistryRaw struct { + Contract *GlobalNotaryRegistry // Generic contract binding to access the raw methods on } -// IMessageRecipientCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type IMessageRecipientCallerRaw struct { - Contract *IMessageRecipientCaller // Generic read-only contract binding to access the raw methods on +// GlobalNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryCallerRaw struct { + Contract *GlobalNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on } -// IMessageRecipientTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type IMessageRecipientTransactorRaw struct { - Contract *IMessageRecipientTransactor // Generic write-only contract binding to access the raw methods on +// GlobalNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GlobalNotaryRegistryTransactorRaw struct { + Contract *GlobalNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on } -// NewIMessageRecipient creates a new instance of IMessageRecipient, bound to a specific deployed contract. -func NewIMessageRecipient(address common.Address, backend bind.ContractBackend) (*IMessageRecipient, error) { - contract, err := bindIMessageRecipient(address, backend, backend, backend) +// NewGlobalNotaryRegistry creates a new instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistry(address common.Address, backend bind.ContractBackend) (*GlobalNotaryRegistry, error) { + contract, err := bindGlobalNotaryRegistry(address, backend, backend, backend) if err != nil { return nil, err } - return &IMessageRecipient{IMessageRecipientCaller: IMessageRecipientCaller{contract: contract}, IMessageRecipientTransactor: IMessageRecipientTransactor{contract: contract}, IMessageRecipientFilterer: IMessageRecipientFilterer{contract: contract}}, nil + return &GlobalNotaryRegistry{GlobalNotaryRegistryCaller: GlobalNotaryRegistryCaller{contract: contract}, GlobalNotaryRegistryTransactor: GlobalNotaryRegistryTransactor{contract: contract}, GlobalNotaryRegistryFilterer: GlobalNotaryRegistryFilterer{contract: contract}}, nil } -// NewIMessageRecipientCaller creates a new read-only instance of IMessageRecipient, bound to a specific deployed contract. -func NewIMessageRecipientCaller(address common.Address, caller bind.ContractCaller) (*IMessageRecipientCaller, error) { - contract, err := bindIMessageRecipient(address, caller, nil, nil) +// NewGlobalNotaryRegistryCaller creates a new read-only instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*GlobalNotaryRegistryCaller, error) { + contract, err := bindGlobalNotaryRegistry(address, caller, nil, nil) if err != nil { return nil, err } - return &IMessageRecipientCaller{contract: contract}, nil + return &GlobalNotaryRegistryCaller{contract: contract}, nil } -// NewIMessageRecipientTransactor creates a new write-only instance of IMessageRecipient, bound to a specific deployed contract. -func NewIMessageRecipientTransactor(address common.Address, transactor bind.ContractTransactor) (*IMessageRecipientTransactor, error) { - contract, err := bindIMessageRecipient(address, nil, transactor, nil) +// NewGlobalNotaryRegistryTransactor creates a new write-only instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*GlobalNotaryRegistryTransactor, error) { + contract, err := bindGlobalNotaryRegistry(address, nil, transactor, nil) if err != nil { return nil, err } - return &IMessageRecipientTransactor{contract: contract}, nil + return &GlobalNotaryRegistryTransactor{contract: contract}, nil } -// NewIMessageRecipientFilterer creates a new log filterer instance of IMessageRecipient, bound to a specific deployed contract. -func NewIMessageRecipientFilterer(address common.Address, filterer bind.ContractFilterer) (*IMessageRecipientFilterer, error) { - contract, err := bindIMessageRecipient(address, nil, nil, filterer) +// NewGlobalNotaryRegistryFilterer creates a new log filterer instance of GlobalNotaryRegistry, bound to a specific deployed contract. +func NewGlobalNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*GlobalNotaryRegistryFilterer, error) { + contract, err := bindGlobalNotaryRegistry(address, nil, nil, filterer) if err != nil { return nil, err } - return &IMessageRecipientFilterer{contract: contract}, nil + return &GlobalNotaryRegistryFilterer{contract: contract}, nil } -// bindIMessageRecipient binds a generic wrapper to an already deployed contract. -func bindIMessageRecipient(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(IMessageRecipientABI)) +// bindGlobalNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindGlobalNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(GlobalNotaryRegistryABI)) if err != nil { return nil, err } @@ -1453,175 +1619,468 @@ func bindIMessageRecipient(address common.Address, caller bind.ContractCaller, t // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_IMessageRecipient *IMessageRecipientRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IMessageRecipient.Contract.IMessageRecipientCaller.contract.Call(opts, result, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_IMessageRecipient *IMessageRecipientRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IMessageRecipient.Contract.IMessageRecipientTransactor.contract.Transfer(opts) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_IMessageRecipient *IMessageRecipientRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IMessageRecipient.Contract.IMessageRecipientTransactor.contract.Transact(opts, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.GlobalNotaryRegistryTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_IMessageRecipient *IMessageRecipientCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IMessageRecipient.Contract.contract.Call(opts, result, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GlobalNotaryRegistry.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_IMessageRecipient *IMessageRecipientTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IMessageRecipient.Contract.contract.Transfer(opts) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_IMessageRecipient *IMessageRecipientTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IMessageRecipient.Contract.contract.Transact(opts, method, params...) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GlobalNotaryRegistry.Contract.contract.Transact(opts, method, params...) } -// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. -// -// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() -func (_IMessageRecipient *IMessageRecipientTransactor) Handle(opts *bind.TransactOpts, _origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { - return _IMessageRecipient.contract.Transact(opts, "handle", _origin, _nonce, _sender, _rootTimestamp, _message) -} +// GlobalNotaryRegistryNotaryAddedIterator is returned from FilterNotaryAdded and is used to iterate over the raw logs and unpacked data for NotaryAdded events raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryAddedIterator struct { + Event *GlobalNotaryRegistryNotaryAdded // Event containing the contract specifics and raw log -// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. -// -// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() -func (_IMessageRecipient *IMessageRecipientSession) Handle(_origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { - return _IMessageRecipient.Contract.Handle(&_IMessageRecipient.TransactOpts, _origin, _nonce, _sender, _rootTimestamp, _message) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. -// -// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() -func (_IMessageRecipient *IMessageRecipientTransactorSession) Handle(_origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { - return _IMessageRecipient.Contract.Handle(&_IMessageRecipient.TransactOpts, _origin, _nonce, _sender, _rootTimestamp, _message) + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// ISystemMessengerMetaData contains all meta data concerning the ISystemMessenger contract. -var ISystemMessengerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enumISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "0d1e27a7": "sendSystemMessage(uint32,uint8,bytes)", - }, -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GlobalNotaryRegistryNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GlobalNotaryRegistryNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// ISystemMessengerABI is the input ABI used to generate the binding from. -// Deprecated: Use ISystemMessengerMetaData.ABI instead. -var ISystemMessengerABI = ISystemMessengerMetaData.ABI + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GlobalNotaryRegistryNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Deprecated: Use ISystemMessengerMetaData.Sigs instead. -// ISystemMessengerFuncSigs maps the 4-byte function signature to its string representation. -var ISystemMessengerFuncSigs = ISystemMessengerMetaData.Sigs + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} -// ISystemMessenger is an auto generated Go binding around an Ethereum contract. -type ISystemMessenger struct { - ISystemMessengerCaller // Read-only binding to the contract - ISystemMessengerTransactor // Write-only binding to the contract - ISystemMessengerFilterer // Log filterer for contract events +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GlobalNotaryRegistryNotaryAddedIterator) Error() error { + return it.fail } -// ISystemMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. -type ISystemMessengerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GlobalNotaryRegistryNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// ISystemMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ISystemMessengerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GlobalNotaryRegistryNotaryAdded represents a NotaryAdded event raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryAdded struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// ISystemMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ISystemMessengerFilterer struct { +// FilterNotaryAdded is a free log retrieval operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) FilterNotaryAdded(opts *bind.FilterOpts, domain []uint32) (*GlobalNotaryRegistryNotaryAddedIterator, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.FilterLogs(opts, "NotaryAdded", domainRule) + if err != nil { + return nil, err + } + return &GlobalNotaryRegistryNotaryAddedIterator{contract: _GlobalNotaryRegistry.contract, event: "NotaryAdded", logs: logs, sub: sub}, nil +} + +// WatchNotaryAdded is a free log subscription operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) WatchNotaryAdded(opts *bind.WatchOpts, sink chan<- *GlobalNotaryRegistryNotaryAdded, domain []uint32) (event.Subscription, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.WatchLogs(opts, "NotaryAdded", domainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GlobalNotaryRegistryNotaryAdded) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNotaryAdded is a log parse operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) ParseNotaryAdded(log types.Log) (*GlobalNotaryRegistryNotaryAdded, error) { + event := new(GlobalNotaryRegistryNotaryAdded) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GlobalNotaryRegistryNotaryRemovedIterator is returned from FilterNotaryRemoved and is used to iterate over the raw logs and unpacked data for NotaryRemoved events raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryRemovedIterator struct { + Event *GlobalNotaryRegistryNotaryRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GlobalNotaryRegistryNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GlobalNotaryRegistryNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GlobalNotaryRegistryNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GlobalNotaryRegistryNotaryRemoved represents a NotaryRemoved event raised by the GlobalNotaryRegistry contract. +type GlobalNotaryRegistryNotaryRemoved struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNotaryRemoved is a free log retrieval operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) FilterNotaryRemoved(opts *bind.FilterOpts, domain []uint32) (*GlobalNotaryRegistryNotaryRemovedIterator, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.FilterLogs(opts, "NotaryRemoved", domainRule) + if err != nil { + return nil, err + } + return &GlobalNotaryRegistryNotaryRemovedIterator{contract: _GlobalNotaryRegistry.contract, event: "NotaryRemoved", logs: logs, sub: sub}, nil +} + +// WatchNotaryRemoved is a free log subscription operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) WatchNotaryRemoved(opts *bind.WatchOpts, sink chan<- *GlobalNotaryRegistryNotaryRemoved, domain []uint32) (event.Subscription, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _GlobalNotaryRegistry.contract.WatchLogs(opts, "NotaryRemoved", domainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GlobalNotaryRegistryNotaryRemoved) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNotaryRemoved is a log parse operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_GlobalNotaryRegistry *GlobalNotaryRegistryFilterer) ParseNotaryRemoved(log types.Log) (*GlobalNotaryRegistryNotaryRemoved, error) { + event := new(GlobalNotaryRegistryNotaryRemoved) + if err := _GlobalNotaryRegistry.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// GuardRegistryMetaData contains all meta data concerning the GuardRegistry contract. +var GuardRegistryMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "9fe03fa2": "allGuards()", + "629ddf69": "getGuard(uint256)", + "246c2449": "guardsAmount()", + }, + Bin: "0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220ce6a74d10a941b0e09b176e9e0e31acd9feeb3ce34afeac0aa68470f3be1d27364736f6c634300080d0033", +} + +// GuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use GuardRegistryMetaData.ABI instead. +var GuardRegistryABI = GuardRegistryMetaData.ABI + +// Deprecated: Use GuardRegistryMetaData.Sigs instead. +// GuardRegistryFuncSigs maps the 4-byte function signature to its string representation. +var GuardRegistryFuncSigs = GuardRegistryMetaData.Sigs + +// GuardRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GuardRegistryMetaData.Bin instead. +var GuardRegistryBin = GuardRegistryMetaData.Bin + +// DeployGuardRegistry deploys a new Ethereum contract, binding an instance of GuardRegistry to it. +func DeployGuardRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GuardRegistry, error) { + parsed, err := GuardRegistryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GuardRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil +} + +// GuardRegistry is an auto generated Go binding around an Ethereum contract. +type GuardRegistry struct { + GuardRegistryCaller // Read-only binding to the contract + GuardRegistryTransactor // Write-only binding to the contract + GuardRegistryFilterer // Log filterer for contract events +} + +// GuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type GuardRegistryCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ISystemMessengerSession is an auto generated Go binding around an Ethereum contract, +// GuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// GuardRegistrySession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ISystemMessengerSession struct { - Contract *ISystemMessenger // Generic contract binding to set the session for +type GuardRegistrySession struct { + Contract *GuardRegistry // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ISystemMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// GuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ISystemMessengerCallerSession struct { - Contract *ISystemMessengerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type GuardRegistryCallerSession struct { + Contract *GuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ISystemMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// GuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ISystemMessengerTransactorSession struct { - Contract *ISystemMessengerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type GuardRegistryTransactorSession struct { + Contract *GuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ISystemMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. -type ISystemMessengerRaw struct { - Contract *ISystemMessenger // Generic contract binding to access the raw methods on +// GuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type GuardRegistryRaw struct { + Contract *GuardRegistry // Generic contract binding to access the raw methods on } -// ISystemMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ISystemMessengerCallerRaw struct { - Contract *ISystemMessengerCaller // Generic read-only contract binding to access the raw methods on +// GuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GuardRegistryCallerRaw struct { + Contract *GuardRegistryCaller // Generic read-only contract binding to access the raw methods on } -// ISystemMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ISystemMessengerTransactorRaw struct { - Contract *ISystemMessengerTransactor // Generic write-only contract binding to access the raw methods on +// GuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GuardRegistryTransactorRaw struct { + Contract *GuardRegistryTransactor // Generic write-only contract binding to access the raw methods on } -// NewISystemMessenger creates a new instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessenger(address common.Address, backend bind.ContractBackend) (*ISystemMessenger, error) { - contract, err := bindISystemMessenger(address, backend, backend, backend) +// NewGuardRegistry creates a new instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistry(address common.Address, backend bind.ContractBackend) (*GuardRegistry, error) { + contract, err := bindGuardRegistry(address, backend, backend, backend) if err != nil { return nil, err } - return &ISystemMessenger{ISystemMessengerCaller: ISystemMessengerCaller{contract: contract}, ISystemMessengerTransactor: ISystemMessengerTransactor{contract: contract}, ISystemMessengerFilterer: ISystemMessengerFilterer{contract: contract}}, nil + return &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil } -// NewISystemMessengerCaller creates a new read-only instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerCaller(address common.Address, caller bind.ContractCaller) (*ISystemMessengerCaller, error) { - contract, err := bindISystemMessenger(address, caller, nil, nil) +// NewGuardRegistryCaller creates a new read-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*GuardRegistryCaller, error) { + contract, err := bindGuardRegistry(address, caller, nil, nil) if err != nil { return nil, err } - return &ISystemMessengerCaller{contract: contract}, nil + return &GuardRegistryCaller{contract: contract}, nil } -// NewISystemMessengerTransactor creates a new write-only instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*ISystemMessengerTransactor, error) { - contract, err := bindISystemMessenger(address, nil, transactor, nil) +// NewGuardRegistryTransactor creates a new write-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*GuardRegistryTransactor, error) { + contract, err := bindGuardRegistry(address, nil, transactor, nil) if err != nil { return nil, err } - return &ISystemMessengerTransactor{contract: contract}, nil + return &GuardRegistryTransactor{contract: contract}, nil } -// NewISystemMessengerFilterer creates a new log filterer instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*ISystemMessengerFilterer, error) { - contract, err := bindISystemMessenger(address, nil, nil, filterer) +// NewGuardRegistryFilterer creates a new log filterer instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*GuardRegistryFilterer, error) { + contract, err := bindGuardRegistry(address, nil, nil, filterer) if err != nil { return nil, err } - return &ISystemMessengerFilterer{contract: contract}, nil + return &GuardRegistryFilterer{contract: contract}, nil } -// bindISystemMessenger binds a generic wrapper to an already deployed contract. -func bindISystemMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ISystemMessengerABI)) +// bindGuardRegistry binds a generic wrapper to an already deployed contract. +func bindGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(GuardRegistryABI)) if err != nil { return nil, err } @@ -1632,215 +2091,270 @@ func bindISystemMessenger(address common.Address, caller bind.ContractCaller, tr // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ISystemMessenger *ISystemMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ISystemMessenger.Contract.ISystemMessengerCaller.contract.Call(opts, result, method, params...) +func (_GuardRegistry *GuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.GuardRegistryCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ISystemMessenger *ISystemMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transfer(opts) +func (_GuardRegistry *GuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ISystemMessenger *ISystemMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transact(opts, method, params...) +func (_GuardRegistry *GuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ISystemMessenger *ISystemMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ISystemMessenger.Contract.contract.Call(opts, result, method, params...) +func (_GuardRegistry *GuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ISystemMessenger.Contract.contract.Transfer(opts) +func (_GuardRegistry *GuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ISystemMessenger.Contract.contract.Transact(opts, method, params...) +func (_GuardRegistry *GuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transact(opts, method, params...) } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerTransactor) SendSystemMessage(opts *bind.TransactOpts, _destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.contract.Transact(opts, "sendSystemMessage", _destDomain, _recipient, _payload) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _GuardRegistry.contract.Call(opts, &out, "allGuards") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistrySession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerTransactorSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCallerSession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// InitializableMetaData contains all meta data concerning the Initializable contract. -var InitializableMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", -} +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _GuardRegistry.contract.Call(opts, &out, "getGuard", _index) -// InitializableABI is the input ABI used to generate the binding from. -// Deprecated: Use InitializableMetaData.ABI instead. -var InitializableABI = InitializableMetaData.ABI + if err != nil { + return *new(common.Address), err + } -// Initializable is an auto generated Go binding around an Ethereum contract. -type Initializable struct { - InitializableCaller // Read-only binding to the contract - InitializableTransactor // Write-only binding to the contract - InitializableFilterer // Log filterer for contract events -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) -// InitializableCaller is an auto generated read-only Go binding around an Ethereum contract. -type InitializableCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} + return out0, err -// InitializableTransactor is an auto generated write-only Go binding around an Ethereum contract. -type InitializableTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// InitializableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type InitializableFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistrySession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// InitializableSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type InitializableSession struct { - Contract *Initializable // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// InitializableCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type InitializableCallerSession struct { - Contract *InitializableCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _GuardRegistry.contract.Call(opts, &out, "guardsAmount") -// InitializableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type InitializableTransactorSession struct { - Contract *InitializableTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} + if err != nil { + return *new(*big.Int), err + } -// InitializableRaw is an auto generated low-level Go binding around an Ethereum contract. -type InitializableRaw struct { - Contract *Initializable // Generic contract binding to access the raw methods on -} + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err -// InitializableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type InitializableCallerRaw struct { - Contract *InitializableCaller // Generic read-only contract binding to access the raw methods on } -// InitializableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type InitializableTransactorRaw struct { - Contract *InitializableTransactor // Generic write-only contract binding to access the raw methods on +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistrySession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// NewInitializable creates a new instance of Initializable, bound to a specific deployed contract. -func NewInitializable(address common.Address, backend bind.ContractBackend) (*Initializable, error) { - contract, err := bindInitializable(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Initializable{InitializableCaller: InitializableCaller{contract: contract}, InitializableTransactor: InitializableTransactor{contract: contract}, InitializableFilterer: InitializableFilterer{contract: contract}}, nil +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCallerSession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// NewInitializableCaller creates a new read-only instance of Initializable, bound to a specific deployed contract. -func NewInitializableCaller(address common.Address, caller bind.ContractCaller) (*InitializableCaller, error) { - contract, err := bindInitializable(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &InitializableCaller{contract: contract}, nil +// GuardRegistryGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the GuardRegistry contract. +type GuardRegistryGuardAddedIterator struct { + Event *GuardRegistryGuardAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// NewInitializableTransactor creates a new write-only instance of Initializable, bound to a specific deployed contract. -func NewInitializableTransactor(address common.Address, transactor bind.ContractTransactor) (*InitializableTransactor, error) { - contract, err := bindInitializable(address, nil, transactor, nil) - if err != nil { - return nil, err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GuardRegistryGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } - return &InitializableTransactor{contract: contract}, nil -} + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// NewInitializableFilterer creates a new log filterer instance of Initializable, bound to a specific deployed contract. -func NewInitializableFilterer(address common.Address, filterer bind.ContractFilterer) (*InitializableFilterer, error) { - contract, err := bindInitializable(address, nil, nil, filterer) - if err != nil { - return nil, err + default: + return false + } } - return &InitializableFilterer{contract: contract}, nil -} + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// bindInitializable binds a generic wrapper to an already deployed contract. -func bindInitializable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(InitializableABI)) - if err != nil { - return nil, err + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Initializable *InitializableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Initializable.Contract.InitializableCaller.contract.Call(opts, result, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GuardRegistryGuardAddedIterator) Error() error { + return it.fail } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Initializable *InitializableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Initializable.Contract.InitializableTransactor.contract.Transfer(opts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardRegistryGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transact invokes the (paid) contract method with params as input values. -func (_Initializable *InitializableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Initializable.Contract.InitializableTransactor.contract.Transact(opts, method, params...) +// GuardRegistryGuardAdded represents a GuardAdded event raised by the GuardRegistry contract. +type GuardRegistryGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Initializable *InitializableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Initializable.Contract.contract.Call(opts, result, method, params...) +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*GuardRegistryGuardAddedIterator, error) { + + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return &GuardRegistryGuardAddedIterator{contract: _GuardRegistry.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Initializable *InitializableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Initializable.Contract.contract.Transfer(opts) +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardAdded) (event.Subscription, error) { + + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// Transact invokes the (paid) contract method with params as input values. -func (_Initializable *InitializableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Initializable.Contract.contract.Transact(opts, method, params...) +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardAdded(log types.Log) (*GuardRegistryGuardAdded, error) { + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// InitializableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Initializable contract. -type InitializableInitializedIterator struct { - Event *InitializableInitialized // Event containing the contract specifics and raw log +// GuardRegistryGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the GuardRegistry contract. +type GuardRegistryGuardRemovedIterator struct { + Event *GuardRegistryGuardRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1854,7 +2368,7 @@ type InitializableInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *InitializableInitializedIterator) Next() bool { +func (it *GuardRegistryGuardRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1863,7 +2377,7 @@ func (it *InitializableInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(InitializableInitialized) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1878,7 +2392,7 @@ func (it *InitializableInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(InitializableInitialized) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1894,41 +2408,41 @@ func (it *InitializableInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *InitializableInitializedIterator) Error() error { +func (it *GuardRegistryGuardRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *InitializableInitializedIterator) Close() error { +func (it *GuardRegistryGuardRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// InitializableInitialized represents a Initialized event raised by the Initializable contract. -type InitializableInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// GuardRegistryGuardRemoved represents a GuardRemoved event raised by the GuardRegistry contract. +type GuardRegistryGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) FilterInitialized(opts *bind.FilterOpts) (*InitializableInitializedIterator, error) { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*GuardRegistryGuardRemovedIterator, error) { - logs, sub, err := _Initializable.contract.FilterLogs(opts, "Initialized") + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardRemoved") if err != nil { return nil, err } - return &InitializableInitializedIterator{contract: _Initializable.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &GuardRegistryGuardRemovedIterator{contract: _GuardRegistry.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *InitializableInitialized) (event.Subscription, error) { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardRemoved) (event.Subscription, error) { - logs, sub, err := _Initializable.contract.WatchLogs(opts, "Initialized") + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardRemoved") if err != nil { return nil, err } @@ -1938,8 +2452,8 @@ func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOp select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(InitializableInitialized) - if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return err } event.Raw = log @@ -1960,35 +2474,35 @@ func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOp }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*InitializableInitialized, error) { - event := new(InitializableInitialized) - if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardRemoved(log types.Log) (*GuardRegistryGuardRemoved, error) { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// MerkleLibMetaData contains all meta data concerning the MerkleLib contract. -var MerkleLibMetaData = &bind.MetaData{ +// HeaderMetaData contains all meta data concerning the Header contract. +var HeaderMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220bd62337655b3df25b537ec57e5be20820b2373f6e1c8885a0c56291e1ece44eb64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207d3257341cdd3bb04530f9b314f4dd3280b9bc08548d24a28d3931411dc7896d64736f6c634300080d0033", } -// MerkleLibABI is the input ABI used to generate the binding from. -// Deprecated: Use MerkleLibMetaData.ABI instead. -var MerkleLibABI = MerkleLibMetaData.ABI +// HeaderABI is the input ABI used to generate the binding from. +// Deprecated: Use HeaderMetaData.ABI instead. +var HeaderABI = HeaderMetaData.ABI -// MerkleLibBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use MerkleLibMetaData.Bin instead. -var MerkleLibBin = MerkleLibMetaData.Bin +// HeaderBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HeaderMetaData.Bin instead. +var HeaderBin = HeaderMetaData.Bin -// DeployMerkleLib deploys a new Ethereum contract, binding an instance of MerkleLib to it. -func DeployMerkleLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MerkleLib, error) { - parsed, err := MerkleLibMetaData.GetAbi() +// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. +func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { + parsed, err := HeaderMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1996,111 +2510,111 @@ func DeployMerkleLib(auth *bind.TransactOpts, backend bind.ContractBackend) (com return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MerkleLibBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil + return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// MerkleLib is an auto generated Go binding around an Ethereum contract. -type MerkleLib struct { - MerkleLibCaller // Read-only binding to the contract - MerkleLibTransactor // Write-only binding to the contract - MerkleLibFilterer // Log filterer for contract events +// Header is an auto generated Go binding around an Ethereum contract. +type Header struct { + HeaderCaller // Read-only binding to the contract + HeaderTransactor // Write-only binding to the contract + HeaderFilterer // Log filterer for contract events } -// MerkleLibCaller is an auto generated read-only Go binding around an Ethereum contract. -type MerkleLibCaller struct { +// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. +type HeaderCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MerkleLibTransactor is an auto generated write-only Go binding around an Ethereum contract. -type MerkleLibTransactor struct { +// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HeaderTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MerkleLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type MerkleLibFilterer struct { +// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HeaderFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MerkleLibSession is an auto generated Go binding around an Ethereum contract, +// HeaderSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type MerkleLibSession struct { - Contract *MerkleLib // Generic contract binding to set the session for +type HeaderSession struct { + Contract *Header // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MerkleLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type MerkleLibCallerSession struct { - Contract *MerkleLibCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type HeaderCallerSession struct { + Contract *HeaderCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// MerkleLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type MerkleLibTransactorSession struct { - Contract *MerkleLibTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type HeaderTransactorSession struct { + Contract *HeaderTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MerkleLibRaw is an auto generated low-level Go binding around an Ethereum contract. -type MerkleLibRaw struct { - Contract *MerkleLib // Generic contract binding to access the raw methods on +// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. +type HeaderRaw struct { + Contract *Header // Generic contract binding to access the raw methods on } -// MerkleLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type MerkleLibCallerRaw struct { - Contract *MerkleLibCaller // Generic read-only contract binding to access the raw methods on +// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HeaderCallerRaw struct { + Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on } -// MerkleLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type MerkleLibTransactorRaw struct { - Contract *MerkleLibTransactor // Generic write-only contract binding to access the raw methods on +// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HeaderTransactorRaw struct { + Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on } -// NewMerkleLib creates a new instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLib(address common.Address, backend bind.ContractBackend) (*MerkleLib, error) { - contract, err := bindMerkleLib(address, backend, backend, backend) +// NewHeader creates a new instance of Header, bound to a specific deployed contract. +func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { + contract, err := bindHeader(address, backend, backend, backend) if err != nil { return nil, err } - return &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil + return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// NewMerkleLibCaller creates a new read-only instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibCaller(address common.Address, caller bind.ContractCaller) (*MerkleLibCaller, error) { - contract, err := bindMerkleLib(address, caller, nil, nil) +// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. +func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { + contract, err := bindHeader(address, caller, nil, nil) if err != nil { return nil, err } - return &MerkleLibCaller{contract: contract}, nil + return &HeaderCaller{contract: contract}, nil } -// NewMerkleLibTransactor creates a new write-only instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibTransactor(address common.Address, transactor bind.ContractTransactor) (*MerkleLibTransactor, error) { - contract, err := bindMerkleLib(address, nil, transactor, nil) +// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. +func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { + contract, err := bindHeader(address, nil, transactor, nil) if err != nil { return nil, err } - return &MerkleLibTransactor{contract: contract}, nil + return &HeaderTransactor{contract: contract}, nil } -// NewMerkleLibFilterer creates a new log filterer instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibFilterer(address common.Address, filterer bind.ContractFilterer) (*MerkleLibFilterer, error) { - contract, err := bindMerkleLib(address, nil, nil, filterer) +// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. +func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { + contract, err := bindHeader(address, nil, nil, filterer) if err != nil { return nil, err } - return &MerkleLibFilterer{contract: contract}, nil + return &HeaderFilterer{contract: contract}, nil } -// bindMerkleLib binds a generic wrapper to an already deployed contract. -func bindMerkleLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(MerkleLibABI)) +// bindHeader binds a generic wrapper to an already deployed contract. +func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HeaderABI)) if err != nil { return nil, err } @@ -2111,169 +2625,154 @@ func bindMerkleLib(address common.Address, caller bind.ContractCaller, transacto // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MerkleLib *MerkleLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MerkleLib.Contract.MerkleLibCaller.contract.Call(opts, result, method, params...) +func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_MerkleLib *MerkleLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MerkleLib.Contract.MerkleLibTransactor.contract.Transfer(opts) +func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_MerkleLib *MerkleLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MerkleLib.Contract.MerkleLibTransactor.contract.Transact(opts, method, params...) +func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MerkleLib *MerkleLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MerkleLib.Contract.contract.Call(opts, result, method, params...) +func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_MerkleLib *MerkleLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MerkleLib.Contract.contract.Transfer(opts) +func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_MerkleLib *MerkleLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MerkleLib.Contract.contract.Transact(opts, method, params...) +func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.contract.Transact(opts, method, params...) } -// MessageMetaData contains all meta data concerning the Message contract. -var MessageMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220cb513ea91c1b35d5b5bf161884a4dda855c268c4213aad201c86506ddfd78de764736f6c634300080d0033", +// IMessageRecipientMetaData contains all meta data concerning the IMessageRecipient contract. +var IMessageRecipientMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_rootTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"handle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "e4d16d62": "handle(uint32,uint32,bytes32,uint256,bytes)", + }, } -// MessageABI is the input ABI used to generate the binding from. -// Deprecated: Use MessageMetaData.ABI instead. -var MessageABI = MessageMetaData.ABI - -// MessageBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use MessageMetaData.Bin instead. -var MessageBin = MessageMetaData.Bin - -// DeployMessage deploys a new Ethereum contract, binding an instance of Message to it. -func DeployMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Message, error) { - parsed, err := MessageMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// IMessageRecipientABI is the input ABI used to generate the binding from. +// Deprecated: Use IMessageRecipientMetaData.ABI instead. +var IMessageRecipientABI = IMessageRecipientMetaData.ABI - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MessageBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil -} +// Deprecated: Use IMessageRecipientMetaData.Sigs instead. +// IMessageRecipientFuncSigs maps the 4-byte function signature to its string representation. +var IMessageRecipientFuncSigs = IMessageRecipientMetaData.Sigs -// Message is an auto generated Go binding around an Ethereum contract. -type Message struct { - MessageCaller // Read-only binding to the contract - MessageTransactor // Write-only binding to the contract - MessageFilterer // Log filterer for contract events +// IMessageRecipient is an auto generated Go binding around an Ethereum contract. +type IMessageRecipient struct { + IMessageRecipientCaller // Read-only binding to the contract + IMessageRecipientTransactor // Write-only binding to the contract + IMessageRecipientFilterer // Log filterer for contract events } -// MessageCaller is an auto generated read-only Go binding around an Ethereum contract. -type MessageCaller struct { +// IMessageRecipientCaller is an auto generated read-only Go binding around an Ethereum contract. +type IMessageRecipientCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type MessageTransactor struct { +// IMessageRecipientTransactor is an auto generated write-only Go binding around an Ethereum contract. +type IMessageRecipientTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type MessageFilterer struct { +// IMessageRecipientFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IMessageRecipientFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageSession is an auto generated Go binding around an Ethereum contract, +// IMessageRecipientSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type MessageSession struct { - Contract *Message // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type IMessageRecipientSession struct { + Contract *IMessageRecipient // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// IMessageRecipientCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type MessageCallerSession struct { - Contract *MessageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type IMessageRecipientCallerSession struct { + Contract *IMessageRecipientCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// MessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// IMessageRecipientTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type MessageTransactorSession struct { - Contract *MessageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type IMessageRecipientTransactorSession struct { + Contract *IMessageRecipientTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MessageRaw is an auto generated low-level Go binding around an Ethereum contract. -type MessageRaw struct { - Contract *Message // Generic contract binding to access the raw methods on +// IMessageRecipientRaw is an auto generated low-level Go binding around an Ethereum contract. +type IMessageRecipientRaw struct { + Contract *IMessageRecipient // Generic contract binding to access the raw methods on } -// MessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type MessageCallerRaw struct { - Contract *MessageCaller // Generic read-only contract binding to access the raw methods on +// IMessageRecipientCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IMessageRecipientCallerRaw struct { + Contract *IMessageRecipientCaller // Generic read-only contract binding to access the raw methods on } -// MessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type MessageTransactorRaw struct { - Contract *MessageTransactor // Generic write-only contract binding to access the raw methods on +// IMessageRecipientTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IMessageRecipientTransactorRaw struct { + Contract *IMessageRecipientTransactor // Generic write-only contract binding to access the raw methods on } -// NewMessage creates a new instance of Message, bound to a specific deployed contract. -func NewMessage(address common.Address, backend bind.ContractBackend) (*Message, error) { - contract, err := bindMessage(address, backend, backend, backend) +// NewIMessageRecipient creates a new instance of IMessageRecipient, bound to a specific deployed contract. +func NewIMessageRecipient(address common.Address, backend bind.ContractBackend) (*IMessageRecipient, error) { + contract, err := bindIMessageRecipient(address, backend, backend, backend) if err != nil { return nil, err } - return &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil + return &IMessageRecipient{IMessageRecipientCaller: IMessageRecipientCaller{contract: contract}, IMessageRecipientTransactor: IMessageRecipientTransactor{contract: contract}, IMessageRecipientFilterer: IMessageRecipientFilterer{contract: contract}}, nil } -// NewMessageCaller creates a new read-only instance of Message, bound to a specific deployed contract. -func NewMessageCaller(address common.Address, caller bind.ContractCaller) (*MessageCaller, error) { - contract, err := bindMessage(address, caller, nil, nil) - if err != nil { +// NewIMessageRecipientCaller creates a new read-only instance of IMessageRecipient, bound to a specific deployed contract. +func NewIMessageRecipientCaller(address common.Address, caller bind.ContractCaller) (*IMessageRecipientCaller, error) { + contract, err := bindIMessageRecipient(address, caller, nil, nil) + if err != nil { return nil, err } - return &MessageCaller{contract: contract}, nil + return &IMessageRecipientCaller{contract: contract}, nil } -// NewMessageTransactor creates a new write-only instance of Message, bound to a specific deployed contract. -func NewMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*MessageTransactor, error) { - contract, err := bindMessage(address, nil, transactor, nil) +// NewIMessageRecipientTransactor creates a new write-only instance of IMessageRecipient, bound to a specific deployed contract. +func NewIMessageRecipientTransactor(address common.Address, transactor bind.ContractTransactor) (*IMessageRecipientTransactor, error) { + contract, err := bindIMessageRecipient(address, nil, transactor, nil) if err != nil { return nil, err } - return &MessageTransactor{contract: contract}, nil + return &IMessageRecipientTransactor{contract: contract}, nil } -// NewMessageFilterer creates a new log filterer instance of Message, bound to a specific deployed contract. -func NewMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*MessageFilterer, error) { - contract, err := bindMessage(address, nil, nil, filterer) +// NewIMessageRecipientFilterer creates a new log filterer instance of IMessageRecipient, bound to a specific deployed contract. +func NewIMessageRecipientFilterer(address common.Address, filterer bind.ContractFilterer) (*IMessageRecipientFilterer, error) { + contract, err := bindIMessageRecipient(address, nil, nil, filterer) if err != nil { return nil, err } - return &MessageFilterer{contract: contract}, nil + return &IMessageRecipientFilterer{contract: contract}, nil } -// bindMessage binds a generic wrapper to an already deployed contract. -func bindMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(MessageABI)) +// bindIMessageRecipient binds a generic wrapper to an already deployed contract. +func bindIMessageRecipient(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(IMessageRecipientABI)) if err != nil { return nil, err } @@ -2284,156 +2783,175 @@ func bindMessage(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Message *MessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Message.Contract.MessageCaller.contract.Call(opts, result, method, params...) +func (_IMessageRecipient *IMessageRecipientRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IMessageRecipient.Contract.IMessageRecipientCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Message *MessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Message.Contract.MessageTransactor.contract.Transfer(opts) +func (_IMessageRecipient *IMessageRecipientRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IMessageRecipient.Contract.IMessageRecipientTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Message *MessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Message.Contract.MessageTransactor.contract.Transact(opts, method, params...) +func (_IMessageRecipient *IMessageRecipientRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IMessageRecipient.Contract.IMessageRecipientTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Message *MessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Message.Contract.contract.Call(opts, result, method, params...) +func (_IMessageRecipient *IMessageRecipientCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IMessageRecipient.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Message *MessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Message.Contract.contract.Transfer(opts) +func (_IMessageRecipient *IMessageRecipientTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IMessageRecipient.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Message.Contract.contract.Transact(opts, method, params...) +func (_IMessageRecipient *IMessageRecipientTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IMessageRecipient.Contract.contract.Transact(opts, method, params...) } -// OwnableUpgradeableMetaData contains all meta data concerning the OwnableUpgradeable contract. -var OwnableUpgradeableMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. +// +// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() +func (_IMessageRecipient *IMessageRecipientTransactor) Handle(opts *bind.TransactOpts, _origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { + return _IMessageRecipient.contract.Transact(opts, "handle", _origin, _nonce, _sender, _rootTimestamp, _message) +} + +// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. +// +// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() +func (_IMessageRecipient *IMessageRecipientSession) Handle(_origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { + return _IMessageRecipient.Contract.Handle(&_IMessageRecipient.TransactOpts, _origin, _nonce, _sender, _rootTimestamp, _message) +} + +// Handle is a paid mutator transaction binding the contract method 0xe4d16d62. +// +// Solidity: function handle(uint32 _origin, uint32 _nonce, bytes32 _sender, uint256 _rootTimestamp, bytes _message) returns() +func (_IMessageRecipient *IMessageRecipientTransactorSession) Handle(_origin uint32, _nonce uint32, _sender [32]byte, _rootTimestamp *big.Int, _message []byte) (*types.Transaction, error) { + return _IMessageRecipient.Contract.Handle(&_IMessageRecipient.TransactOpts, _origin, _nonce, _sender, _rootTimestamp, _message) +} + +// ISystemMessengerMetaData contains all meta data concerning the ISystemMessenger contract. +var ISystemMessengerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enumISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Sigs: map[string]string{ - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "f2fde38b": "transferOwnership(address)", + "0d1e27a7": "sendSystemMessage(uint32,uint8,bytes)", }, } -// OwnableUpgradeableABI is the input ABI used to generate the binding from. -// Deprecated: Use OwnableUpgradeableMetaData.ABI instead. -var OwnableUpgradeableABI = OwnableUpgradeableMetaData.ABI +// ISystemMessengerABI is the input ABI used to generate the binding from. +// Deprecated: Use ISystemMessengerMetaData.ABI instead. +var ISystemMessengerABI = ISystemMessengerMetaData.ABI -// Deprecated: Use OwnableUpgradeableMetaData.Sigs instead. -// OwnableUpgradeableFuncSigs maps the 4-byte function signature to its string representation. -var OwnableUpgradeableFuncSigs = OwnableUpgradeableMetaData.Sigs +// Deprecated: Use ISystemMessengerMetaData.Sigs instead. +// ISystemMessengerFuncSigs maps the 4-byte function signature to its string representation. +var ISystemMessengerFuncSigs = ISystemMessengerMetaData.Sigs -// OwnableUpgradeable is an auto generated Go binding around an Ethereum contract. -type OwnableUpgradeable struct { - OwnableUpgradeableCaller // Read-only binding to the contract - OwnableUpgradeableTransactor // Write-only binding to the contract - OwnableUpgradeableFilterer // Log filterer for contract events +// ISystemMessenger is an auto generated Go binding around an Ethereum contract. +type ISystemMessenger struct { + ISystemMessengerCaller // Read-only binding to the contract + ISystemMessengerTransactor // Write-only binding to the contract + ISystemMessengerFilterer // Log filterer for contract events } -// OwnableUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. -type OwnableUpgradeableCaller struct { +// ISystemMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ISystemMessengerCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. -type OwnableUpgradeableTransactor struct { +// ISystemMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ISystemMessengerTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type OwnableUpgradeableFilterer struct { +// ISystemMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ISystemMessengerFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// ISystemMessengerSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type OwnableUpgradeableSession struct { - Contract *OwnableUpgradeable // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type ISystemMessengerSession struct { + Contract *ISystemMessenger // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// ISystemMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type OwnableUpgradeableCallerSession struct { - Contract *OwnableUpgradeableCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type ISystemMessengerCallerSession struct { + Contract *ISystemMessengerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// OwnableUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// ISystemMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type OwnableUpgradeableTransactorSession struct { - Contract *OwnableUpgradeableTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type ISystemMessengerTransactorSession struct { + Contract *ISystemMessengerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. -type OwnableUpgradeableRaw struct { - Contract *OwnableUpgradeable // Generic contract binding to access the raw methods on +// ISystemMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ISystemMessengerRaw struct { + Contract *ISystemMessenger // Generic contract binding to access the raw methods on } -// OwnableUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type OwnableUpgradeableCallerRaw struct { - Contract *OwnableUpgradeableCaller // Generic read-only contract binding to access the raw methods on +// ISystemMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ISystemMessengerCallerRaw struct { + Contract *ISystemMessengerCaller // Generic read-only contract binding to access the raw methods on } -// OwnableUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type OwnableUpgradeableTransactorRaw struct { - Contract *OwnableUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +// ISystemMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ISystemMessengerTransactorRaw struct { + Contract *ISystemMessengerTransactor // Generic write-only contract binding to access the raw methods on } -// NewOwnableUpgradeable creates a new instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeable(address common.Address, backend bind.ContractBackend) (*OwnableUpgradeable, error) { - contract, err := bindOwnableUpgradeable(address, backend, backend, backend) +// NewISystemMessenger creates a new instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessenger(address common.Address, backend bind.ContractBackend) (*ISystemMessenger, error) { + contract, err := bindISystemMessenger(address, backend, backend, backend) if err != nil { return nil, err } - return &OwnableUpgradeable{OwnableUpgradeableCaller: OwnableUpgradeableCaller{contract: contract}, OwnableUpgradeableTransactor: OwnableUpgradeableTransactor{contract: contract}, OwnableUpgradeableFilterer: OwnableUpgradeableFilterer{contract: contract}}, nil + return &ISystemMessenger{ISystemMessengerCaller: ISystemMessengerCaller{contract: contract}, ISystemMessengerTransactor: ISystemMessengerTransactor{contract: contract}, ISystemMessengerFilterer: ISystemMessengerFilterer{contract: contract}}, nil } -// NewOwnableUpgradeableCaller creates a new read-only instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*OwnableUpgradeableCaller, error) { - contract, err := bindOwnableUpgradeable(address, caller, nil, nil) +// NewISystemMessengerCaller creates a new read-only instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerCaller(address common.Address, caller bind.ContractCaller) (*ISystemMessengerCaller, error) { + contract, err := bindISystemMessenger(address, caller, nil, nil) if err != nil { return nil, err } - return &OwnableUpgradeableCaller{contract: contract}, nil + return &ISystemMessengerCaller{contract: contract}, nil } -// NewOwnableUpgradeableTransactor creates a new write-only instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableUpgradeableTransactor, error) { - contract, err := bindOwnableUpgradeable(address, nil, transactor, nil) +// NewISystemMessengerTransactor creates a new write-only instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*ISystemMessengerTransactor, error) { + contract, err := bindISystemMessenger(address, nil, transactor, nil) if err != nil { return nil, err } - return &OwnableUpgradeableTransactor{contract: contract}, nil + return &ISystemMessengerTransactor{contract: contract}, nil } -// NewOwnableUpgradeableFilterer creates a new log filterer instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableUpgradeableFilterer, error) { - contract, err := bindOwnableUpgradeable(address, nil, nil, filterer) +// NewISystemMessengerFilterer creates a new log filterer instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*ISystemMessengerFilterer, error) { + contract, err := bindISystemMessenger(address, nil, nil, filterer) if err != nil { return nil, err } - return &OwnableUpgradeableFilterer{contract: contract}, nil + return &ISystemMessengerFilterer{contract: contract}, nil } -// bindOwnableUpgradeable binds a generic wrapper to an already deployed contract. -func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(OwnableUpgradeableABI)) +// bindISystemMessenger binds a generic wrapper to an already deployed contract. +func bindISystemMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ISystemMessengerABI)) if err != nil { return nil, err } @@ -2444,116 +2962,215 @@ func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _OwnableUpgradeable.Contract.OwnableUpgradeableCaller.contract.Call(opts, result, method, params...) +func (_ISystemMessenger *ISystemMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ISystemMessenger.Contract.ISystemMessengerCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transfer(opts) +func (_ISystemMessenger *ISystemMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transact(opts, method, params...) +func (_ISystemMessenger *ISystemMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_OwnableUpgradeable *OwnableUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _OwnableUpgradeable.Contract.contract.Call(opts, result, method, params...) +func (_ISystemMessenger *ISystemMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ISystemMessenger.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.contract.Transfer(opts) +func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ISystemMessenger.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.contract.Transact(opts, method, params...) +func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ISystemMessenger.Contract.contract.Transact(opts, method, params...) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. // -// Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _OwnableUpgradeable.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerTransactor) SendSystemMessage(opts *bind.TransactOpts, _destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.contract.Transact(opts, "sendSystemMessage", _destDomain, _recipient, _payload) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. // -// Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableSession) Owner() (common.Address, error) { - return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. // -// Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableCallerSession) Owner() (common.Address, error) { - return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.contract.Transact(opts, "renounceOwnership") +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerTransactorSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) +// InitializableMetaData contains all meta data concerning the Initializable contract. +var InitializableMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) +// InitializableABI is the input ABI used to generate the binding from. +// Deprecated: Use InitializableMetaData.ABI instead. +var InitializableABI = InitializableMetaData.ABI + +// Initializable is an auto generated Go binding around an Ethereum contract. +type Initializable struct { + InitializableCaller // Read-only binding to the contract + InitializableTransactor // Write-only binding to the contract + InitializableFilterer // Log filterer for contract events } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) +// InitializableCaller is an auto generated read-only Go binding around an Ethereum contract. +type InitializableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +// InitializableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type InitializableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +// InitializableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type InitializableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the OwnableUpgradeable contract. -type OwnableUpgradeableInitializedIterator struct { - Event *OwnableUpgradeableInitialized // Event containing the contract specifics and raw log +// InitializableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type InitializableSession struct { + Contract *Initializable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InitializableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type InitializableCallerSession struct { + Contract *InitializableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// InitializableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type InitializableTransactorSession struct { + Contract *InitializableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InitializableRaw is an auto generated low-level Go binding around an Ethereum contract. +type InitializableRaw struct { + Contract *Initializable // Generic contract binding to access the raw methods on +} + +// InitializableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type InitializableCallerRaw struct { + Contract *InitializableCaller // Generic read-only contract binding to access the raw methods on +} + +// InitializableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type InitializableTransactorRaw struct { + Contract *InitializableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewInitializable creates a new instance of Initializable, bound to a specific deployed contract. +func NewInitializable(address common.Address, backend bind.ContractBackend) (*Initializable, error) { + contract, err := bindInitializable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Initializable{InitializableCaller: InitializableCaller{contract: contract}, InitializableTransactor: InitializableTransactor{contract: contract}, InitializableFilterer: InitializableFilterer{contract: contract}}, nil +} + +// NewInitializableCaller creates a new read-only instance of Initializable, bound to a specific deployed contract. +func NewInitializableCaller(address common.Address, caller bind.ContractCaller) (*InitializableCaller, error) { + contract, err := bindInitializable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &InitializableCaller{contract: contract}, nil +} + +// NewInitializableTransactor creates a new write-only instance of Initializable, bound to a specific deployed contract. +func NewInitializableTransactor(address common.Address, transactor bind.ContractTransactor) (*InitializableTransactor, error) { + contract, err := bindInitializable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &InitializableTransactor{contract: contract}, nil +} + +// NewInitializableFilterer creates a new log filterer instance of Initializable, bound to a specific deployed contract. +func NewInitializableFilterer(address common.Address, filterer bind.ContractFilterer) (*InitializableFilterer, error) { + contract, err := bindInitializable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &InitializableFilterer{contract: contract}, nil +} + +// bindInitializable binds a generic wrapper to an already deployed contract. +func bindInitializable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(InitializableABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Initializable *InitializableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Initializable.Contract.InitializableCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Initializable *InitializableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Initializable.Contract.InitializableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Initializable *InitializableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Initializable.Contract.InitializableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Initializable *InitializableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Initializable.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Initializable *InitializableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Initializable.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Initializable *InitializableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Initializable.Contract.contract.Transact(opts, method, params...) +} + +// InitializableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Initializable contract. +type InitializableInitializedIterator struct { + Event *InitializableInitialized // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2567,7 +3184,7 @@ type OwnableUpgradeableInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *OwnableUpgradeableInitializedIterator) Next() bool { +func (it *InitializableInitializedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2576,7 +3193,7 @@ func (it *OwnableUpgradeableInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(OwnableUpgradeableInitialized) + it.Event = new(InitializableInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2591,7 +3208,7 @@ func (it *OwnableUpgradeableInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(OwnableUpgradeableInitialized) + it.Event = new(InitializableInitialized) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2607,19 +3224,19 @@ func (it *OwnableUpgradeableInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *OwnableUpgradeableInitializedIterator) Error() error { +func (it *InitializableInitializedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *OwnableUpgradeableInitializedIterator) Close() error { +func (it *InitializableInitializedIterator) Close() error { it.sub.Unsubscribe() return nil } -// OwnableUpgradeableInitialized represents a Initialized event raised by the OwnableUpgradeable contract. -type OwnableUpgradeableInitialized struct { +// InitializableInitialized represents a Initialized event raised by the Initializable contract. +type InitializableInitialized struct { Version uint8 Raw types.Log // Blockchain specific contextual infos } @@ -2627,21 +3244,21 @@ type OwnableUpgradeableInitialized struct { // FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // // Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*OwnableUpgradeableInitializedIterator, error) { +func (_Initializable *InitializableFilterer) FilterInitialized(opts *bind.FilterOpts) (*InitializableInitializedIterator, error) { - logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "Initialized") + logs, sub, err := _Initializable.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &OwnableUpgradeableInitializedIterator{contract: _OwnableUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &InitializableInitializedIterator{contract: _Initializable.contract, event: "Initialized", logs: logs, sub: sub}, nil } // WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // // Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableInitialized) (event.Subscription, error) { +func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *InitializableInitialized) (event.Subscription, error) { - logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "Initialized") + logs, sub, err := _Initializable.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } @@ -2651,8 +3268,8 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bi select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(OwnableUpgradeableInitialized) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(InitializableInitialized) + if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { return err } event.Raw = log @@ -2676,305 +3293,144 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bi // ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // // Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseInitialized(log types.Log) (*OwnableUpgradeableInitialized, error) { - event := new(OwnableUpgradeableInitialized) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { +func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*InitializableInitialized, error) { + event := new(InitializableInitialized) + if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } event.Raw = log return event, nil } -// OwnableUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the OwnableUpgradeable contract. -type OwnableUpgradeableOwnershipTransferredIterator struct { - Event *OwnableUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log +// MerkleLibMetaData contains all meta data concerning the MerkleLib contract. +var MerkleLibMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209f3b9af459a0eb5a59dfc41d8c8a4b26c6a43ff276f126dfc6dba7e8d57d56d164736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// MerkleLibABI is the input ABI used to generate the binding from. +// Deprecated: Use MerkleLibMetaData.ABI instead. +var MerkleLibABI = MerkleLibMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// MerkleLibBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MerkleLibMetaData.Bin instead. +var MerkleLibBin = MerkleLibMetaData.Bin -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(OwnableUpgradeableOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(OwnableUpgradeableOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// OwnableUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the OwnableUpgradeable contract. -type OwnableUpgradeableOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableUpgradeableOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return &OwnableUpgradeableOwnershipTransferredIterator{contract: _OwnableUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } - - logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(OwnableUpgradeableOwnershipTransferred) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableUpgradeableOwnershipTransferred, error) { - event := new(OwnableUpgradeableOwnershipTransferred) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// ReplicaLibMetaData contains all meta data concerning the ReplicaLib contract. -var ReplicaLibMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"MESSAGE_STATUS_NONE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MESSAGE_STATUS_PROCESSED\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "b0075818": "MESSAGE_STATUS_NONE()", - "643d8086": "MESSAGE_STATUS_PROCESSED()", - }, - Bin: "0x6098610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212207d4468c7eb796bb0cde4fd87167c7dffd8650a2327021912be04056d3f1f6ed964736f6c634300080d0033", -} - -// ReplicaLibABI is the input ABI used to generate the binding from. -// Deprecated: Use ReplicaLibMetaData.ABI instead. -var ReplicaLibABI = ReplicaLibMetaData.ABI - -// Deprecated: Use ReplicaLibMetaData.Sigs instead. -// ReplicaLibFuncSigs maps the 4-byte function signature to its string representation. -var ReplicaLibFuncSigs = ReplicaLibMetaData.Sigs - -// ReplicaLibBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ReplicaLibMetaData.Bin instead. -var ReplicaLibBin = ReplicaLibMetaData.Bin - -// DeployReplicaLib deploys a new Ethereum contract, binding an instance of ReplicaLib to it. -func DeployReplicaLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ReplicaLib, error) { - parsed, err := ReplicaLibMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err +// DeployMerkleLib deploys a new Ethereum contract, binding an instance of MerkleLib to it. +func DeployMerkleLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MerkleLib, error) { + parsed, err := MerkleLibMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err } if parsed == nil { return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaLibBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MerkleLibBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ReplicaLib{ReplicaLibCaller: ReplicaLibCaller{contract: contract}, ReplicaLibTransactor: ReplicaLibTransactor{contract: contract}, ReplicaLibFilterer: ReplicaLibFilterer{contract: contract}}, nil + return address, tx, &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil } -// ReplicaLib is an auto generated Go binding around an Ethereum contract. -type ReplicaLib struct { - ReplicaLibCaller // Read-only binding to the contract - ReplicaLibTransactor // Write-only binding to the contract - ReplicaLibFilterer // Log filterer for contract events +// MerkleLib is an auto generated Go binding around an Ethereum contract. +type MerkleLib struct { + MerkleLibCaller // Read-only binding to the contract + MerkleLibTransactor // Write-only binding to the contract + MerkleLibFilterer // Log filterer for contract events } -// ReplicaLibCaller is an auto generated read-only Go binding around an Ethereum contract. -type ReplicaLibCaller struct { +// MerkleLibCaller is an auto generated read-only Go binding around an Ethereum contract. +type MerkleLibCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaLibTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ReplicaLibTransactor struct { +// MerkleLibTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MerkleLibTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ReplicaLibFilterer struct { +// MerkleLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MerkleLibFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaLibSession is an auto generated Go binding around an Ethereum contract, +// MerkleLibSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ReplicaLibSession struct { - Contract *ReplicaLib // Generic contract binding to set the session for +type MerkleLibSession struct { + Contract *MerkleLib // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ReplicaLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// MerkleLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ReplicaLibCallerSession struct { - Contract *ReplicaLibCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type MerkleLibCallerSession struct { + Contract *MerkleLibCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ReplicaLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// MerkleLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ReplicaLibTransactorSession struct { - Contract *ReplicaLibTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type MerkleLibTransactorSession struct { + Contract *MerkleLibTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ReplicaLibRaw is an auto generated low-level Go binding around an Ethereum contract. -type ReplicaLibRaw struct { - Contract *ReplicaLib // Generic contract binding to access the raw methods on +// MerkleLibRaw is an auto generated low-level Go binding around an Ethereum contract. +type MerkleLibRaw struct { + Contract *MerkleLib // Generic contract binding to access the raw methods on } -// ReplicaLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ReplicaLibCallerRaw struct { - Contract *ReplicaLibCaller // Generic read-only contract binding to access the raw methods on +// MerkleLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MerkleLibCallerRaw struct { + Contract *MerkleLibCaller // Generic read-only contract binding to access the raw methods on } -// ReplicaLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ReplicaLibTransactorRaw struct { - Contract *ReplicaLibTransactor // Generic write-only contract binding to access the raw methods on +// MerkleLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MerkleLibTransactorRaw struct { + Contract *MerkleLibTransactor // Generic write-only contract binding to access the raw methods on } -// NewReplicaLib creates a new instance of ReplicaLib, bound to a specific deployed contract. -func NewReplicaLib(address common.Address, backend bind.ContractBackend) (*ReplicaLib, error) { - contract, err := bindReplicaLib(address, backend, backend, backend) +// NewMerkleLib creates a new instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLib(address common.Address, backend bind.ContractBackend) (*MerkleLib, error) { + contract, err := bindMerkleLib(address, backend, backend, backend) if err != nil { return nil, err } - return &ReplicaLib{ReplicaLibCaller: ReplicaLibCaller{contract: contract}, ReplicaLibTransactor: ReplicaLibTransactor{contract: contract}, ReplicaLibFilterer: ReplicaLibFilterer{contract: contract}}, nil + return &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil } -// NewReplicaLibCaller creates a new read-only instance of ReplicaLib, bound to a specific deployed contract. -func NewReplicaLibCaller(address common.Address, caller bind.ContractCaller) (*ReplicaLibCaller, error) { - contract, err := bindReplicaLib(address, caller, nil, nil) +// NewMerkleLibCaller creates a new read-only instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibCaller(address common.Address, caller bind.ContractCaller) (*MerkleLibCaller, error) { + contract, err := bindMerkleLib(address, caller, nil, nil) if err != nil { return nil, err } - return &ReplicaLibCaller{contract: contract}, nil + return &MerkleLibCaller{contract: contract}, nil } -// NewReplicaLibTransactor creates a new write-only instance of ReplicaLib, bound to a specific deployed contract. -func NewReplicaLibTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaLibTransactor, error) { - contract, err := bindReplicaLib(address, nil, transactor, nil) +// NewMerkleLibTransactor creates a new write-only instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibTransactor(address common.Address, transactor bind.ContractTransactor) (*MerkleLibTransactor, error) { + contract, err := bindMerkleLib(address, nil, transactor, nil) if err != nil { return nil, err } - return &ReplicaLibTransactor{contract: contract}, nil + return &MerkleLibTransactor{contract: contract}, nil } -// NewReplicaLibFilterer creates a new log filterer instance of ReplicaLib, bound to a specific deployed contract. -func NewReplicaLibFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaLibFilterer, error) { - contract, err := bindReplicaLib(address, nil, nil, filterer) +// NewMerkleLibFilterer creates a new log filterer instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibFilterer(address common.Address, filterer bind.ContractFilterer) (*MerkleLibFilterer, error) { + contract, err := bindMerkleLib(address, nil, nil, filterer) if err != nil { return nil, err } - return &ReplicaLibFilterer{contract: contract}, nil + return &MerkleLibFilterer{contract: contract}, nil } -// bindReplicaLib binds a generic wrapper to an already deployed contract. -func bindReplicaLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ReplicaLibABI)) +// bindMerkleLib binds a generic wrapper to an already deployed contract. +func bindMerkleLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MerkleLibABI)) if err != nil { return nil, err } @@ -2985,144 +3441,57 @@ func bindReplicaLib(address common.Address, caller bind.ContractCaller, transact // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ReplicaLib *ReplicaLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaLib.Contract.ReplicaLibCaller.contract.Call(opts, result, method, params...) -} +func (_MerkleLib *MerkleLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MerkleLib.Contract.MerkleLibCaller.contract.Call(opts, result, method, params...) +} // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ReplicaLib *ReplicaLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaLib.Contract.ReplicaLibTransactor.contract.Transfer(opts) +func (_MerkleLib *MerkleLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MerkleLib.Contract.MerkleLibTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ReplicaLib *ReplicaLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaLib.Contract.ReplicaLibTransactor.contract.Transact(opts, method, params...) +func (_MerkleLib *MerkleLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MerkleLib.Contract.MerkleLibTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ReplicaLib *ReplicaLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaLib.Contract.contract.Call(opts, result, method, params...) +func (_MerkleLib *MerkleLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MerkleLib.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ReplicaLib *ReplicaLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaLib.Contract.contract.Transfer(opts) +func (_MerkleLib *MerkleLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MerkleLib.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ReplicaLib *ReplicaLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaLib.Contract.contract.Transact(opts, method, params...) -} - -// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. -// -// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) -func (_ReplicaLib *ReplicaLibCaller) MESSAGESTATUSNONE(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _ReplicaLib.contract.Call(opts, &out, "MESSAGE_STATUS_NONE") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. -// -// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) -func (_ReplicaLib *ReplicaLibSession) MESSAGESTATUSNONE() ([32]byte, error) { - return _ReplicaLib.Contract.MESSAGESTATUSNONE(&_ReplicaLib.CallOpts) -} - -// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. -// -// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) -func (_ReplicaLib *ReplicaLibCallerSession) MESSAGESTATUSNONE() ([32]byte, error) { - return _ReplicaLib.Contract.MESSAGESTATUSNONE(&_ReplicaLib.CallOpts) -} - -// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. -// -// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) -func (_ReplicaLib *ReplicaLibCaller) MESSAGESTATUSPROCESSED(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _ReplicaLib.contract.Call(opts, &out, "MESSAGE_STATUS_PROCESSED") - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. -// -// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) -func (_ReplicaLib *ReplicaLibSession) MESSAGESTATUSPROCESSED() ([32]byte, error) { - return _ReplicaLib.Contract.MESSAGESTATUSPROCESSED(&_ReplicaLib.CallOpts) -} - -// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. -// -// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) -func (_ReplicaLib *ReplicaLibCallerSession) MESSAGESTATUSPROCESSED() ([32]byte, error) { - return _ReplicaLib.Contract.MESSAGESTATUSPROCESSED(&_ReplicaLib.CallOpts) +func (_MerkleLib *MerkleLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MerkleLib.Contract.contract.Transact(opts, method, params...) } -// ReplicaManagerMetaData contains all meta data concerning the ReplicaManager contract. -var ReplicaManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "ffa1ad74": "VERSION()", - "15a046aa": "acceptableRoot(uint32,uint32,bytes32)", - "7dfdba28": "activeReplicaConfirmedAt(uint32,bytes32)", - "63415514": "activeReplicaMessageStatus(uint32,bytes32)", - "b65672d3": "activeReplicaNonce(uint32)", - "8624c35c": "initialize(uint32,address)", - "8d3638f4": "localDomain()", - "8da5cb5b": "owner()", - "928bc4b2": "process(bytes)", - "4f63be3f": "prove(uint32,bytes,bytes32[32],uint256)", - "68705275": "proveAndProcess(uint32,bytes,bytes32[32],uint256)", - "715018a6": "renounceOwnership()", - "9df7d36d": "setConfirmation(uint32,bytes32,uint256)", - "b7bc563e": "setSystemMessenger(address)", - "9d54f419": "setUpdater(address)", - "f646a512": "submitAttestation(bytes)", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "df034cd0": "updater()", - }, - Bin: "0x60a06040523480156200001157600080fd5b5060405162002dbc38038062002dbc833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612d206200009c60003960008181610256015281816108470152610eb80152612d206000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c8063928bc4b2116100cd578063ccbdf9c911610081578063f2fde38b11610066578063f2fde38b1461038e578063f646a512146103a1578063ffa1ad74146103b457600080fd5b8063ccbdf9c91461034e578063df034cd01461036e57600080fd5b80639df7d36d116100b25780639df7d36d146102f2578063b65672d314610305578063b7bc563e1461033b57600080fd5b8063928bc4b2146102cc5780639d54f419146102df57600080fd5b8063715018a6116101245780638624c35c116101095780638624c35c1461023e5780638d3638f4146102515780638da5cb5b1461028d57600080fd5b8063715018a6146101f55780637dfdba28146101fd57600080fd5b806315a046aa146101565780634f63be3f1461017e578063634155141461019157806368705275146101e0575b600080fd5b610169610164366004612701565b6103ce565b60405190151581526020015b60405180910390f35b61016961018c366004612817565b61042b565b6101d261019f366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b604051908152602001610175565b6101f36101ee366004612817565b6105a5565b005b6101f361060c565b6101d261020b366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101f361024c3660046128d3565b610675565b6102787f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6101f36102da36600461290a565b6107ee565b6101f36102ed36600461293f565b610b8a565b6101f361030036600461295c565b610bfa565b61027861031336600461298f565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101f361034936600461293f565b610cee565b6066546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6101f361039c36600461293f565b610d9c565b6101f36103af36600461290a565b610e95565b6103bc600081565b60405160ff9091168152602001610175565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361040d576000915050610424565b61041d63ffffffff8516826129d9565b4210159150505b9392505050565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff16600281111561047a5761047a6129f1565b146104cc5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561052a5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016104c3565b60006105608387602080602002604051908101604052809291908260208002808284376000920191909152508991506110709050565b60008181526001840160205260409020549091501561059557600092835260029190910160205260409091205550600161059d565b600093505050505b949350505050565b6105b18484848461042b565b6105fd5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016104c3565b610606836107ee565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106735760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b565b60006106816001611116565b905080156106b657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6106bf8261126d565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107708360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc602052604090205580156107e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006107f9826112f2565b9050600061080c62ffffff198316611306565b9050600061081f62ffffff198316611346565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661087662ffffff198516611370565b63ffffffff16146108c95760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016104c3565b60006108da62ffffff198616611391565b60008181526002840160205260409020549091506108f7816113ee565b6109435760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016104c3565b61095c8461095662ffffff198816611402565b836103ce565b6109a85760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016104c3565b60c95460ff166001146109fd5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016104c3565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610a3a610a3762ffffff198816611423565b50565b6000828152600284016020526040812060019055610a65610a6062ffffff19881661145a565b61147b565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610a9362ffffff198a166114bd565b610aa262ffffff198b166114de565b600087815260018a016020526040902054610ad0610ac562ffffff198f166114ff565b62ffffff191661153e565b6040518663ffffffff1660e01b8152600401610af0959493929190612a8b565b600060405180830381600087803b158015610b0a57600080fd5b505af1158015610b1e573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bf15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b610a3781611591565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610ca49083908690869061161716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d555760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b73ffffffffffffffffffffffffffffffffffffffff8116610e8c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104c3565b610a378161162b565b6000610ea0826116a2565b9150506000610eb48262ffffff19166117c3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610f315760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016104c3565b6000610f4262ffffff1984166117d7565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020805492935091811690831611610fbd5760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016104c3565b6000610fce62ffffff1986166117eb565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171611053610ac58a62ffffff1916611800565b6040516110609190612acb565b60405180910390a4505050505050565b8260005b602081101561110e57600183821c16600085836020811061109757611097612ade565b60200201519050816001036110d7576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611104565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611074565b509392505050565b60008054610100900460ff16156111b3578160ff1660011480156111395750303b155b6111ab5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b506000919050565b60005460ff8084169116106112305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166112ea5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610bf1611833565b6000611300826105396118b8565b92915050565b60008161131b62ffffff1982166105396118dc565b5061133d8361132b8560016119dd565b6113368660026119dd565b6001611a0f565b91505b50919050565b60008161135c60015b62ffffff198316906118dc565b5061133d62ffffff19841660026004611a2e565b60008161137d600161134f565b5061133d62ffffff198416602a6004611a2e565b6000806113ac8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006113d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906113005750506001141590565b60008161140f600161134f565b5061133d62ffffff198416604e6004611a2e565b60008161143862ffffff1982166105396118dc565b5061133d836114488560026119dd565b6114538660036119dd565b6002611a0f565b600081611467600161134f565b5061133d62ffffff198416602e6020611a5e565b60007401000000000000000000000000000000000000000082016114b757505060665473ffffffffffffffffffffffffffffffffffffffff1690565b81611300565b6000816114ca600161134f565b5061133d62ffffff19841660266004611a2e565b6000816114eb600161134f565b5061133d62ffffff19841660066020611a5e565b60008161151462ffffff1982166105396118dc565b5061133d836115248560036119dd565b601886901c6bffffffffffffffffffffffff166003611a0f565b606060008061155b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506115808483602001611c1c565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806116af83826118b8565b905060286bffffffffffffffffffffffff601883901c16116117135760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016104c3565b61173c61172562ffffff198316611dc1565b611737610ac562ffffff198516611800565b611dd6565b915061177261175062ffffff1983166117c3565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6117be5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e2075706461746572000000000000000060448201526064016104c3565b915091565b600061130062ffffff198316826004611a2e565b600061130062ffffff198316600480611a2e565b600061130062ffffff19831660086020611a5e565b6000611300602861182381601886901c6bffffffffffffffffffffffff16612b0d565b62ffffff19851691906000611e4d565b600054610100900460ff166118b05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610673611ec7565b8151600090602084016118d364ffffffffff85168284611f4d565b95945050505050565b60006118e88383611f94565b6119d65760006119076118fb8560d81c90565b64ffffffffff16611fb7565b915050600061191c8464ffffffffff16611fb7565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016104c39190612acb565b5090919050565b600061042460028360048111156119f6576119f66129f1565b611a009190612b24565b62ffffff198516906002611a2e565b60006118d384611a1f8186612b0d565b62ffffff198816919085611e4d565b6000611a3b826020612b61565b611a46906008612b84565b60ff16611a54858585611a5e565b901c949350505050565b60008160ff16600003611a7357506000610424565b611a8b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aa660ff8416856129d9565b1115611b1e57611b05611ac78560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aed8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166120a1565b60405162461bcd60e51b81526004016104c39190612acb565b60208260ff161115611b985760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104c3565b600882026000611bb68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611c995760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016104c3565b611ca28361210f565b611d145760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016104c3565b6000611d2e8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611d588560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611d7d5760206060fd5b8285848460045afa50611db7611d938760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061130062ffffff19831682602881611e4d565b600080611de862ffffff198516611391565b9050611e41816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061059d818461214c565b600080611e688660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050611e8186612168565b84611e8c87846129d9565b611e9691906129d9565b1115611ea95762ffffff1991505061059d565b611eb385826129d9565b9050611db78364ffffffffff168286611f4d565b600054610100900460ff16611f445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b6106733361162b565b600080611f5a83856129d9565b9050604051811115611f6a575060005b80600003611f7f5762ffffff19915050610424565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16611fa88460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561202a576000611fd6826008612b84565b60ff1685901c9050611fe7816121b0565b61ffff16841793508160ff1660101461200257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611fbd565b50600f5b60ff8160ff16101561209b576000612047826008612b84565b60ff1685901c9050612058816121b0565b61ffff16831792508160ff1660001461207357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161202e565b50915091565b606060006120ae86611fb7565b91505060006120bc86611fb7565b91505060006120ca86611fb7565b91505060006120d886611fb7565b915050838383836040516020016120f29493929190612bad565b604051602081830303815290604052945050505050949350505050565b600061211b8260d81c90565b64ffffffffff1664ffffffffff0361213557506000919050565b600061214083612168565b60405110199392505050565b600080600061215b85856121e2565b9150915061110e81612250565b60006121828260181c6bffffffffffffffffffffffff1690565b61219a8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006121c260048360ff16901c61243c565b60ff1661ffff919091161760081b6121d98261243c565b60ff1617919050565b60008082516041036122185760208301516040840151606085015160001a61220c87828585612583565b94509450505050612249565b8251604003612241576020830151604084015161223686838361269b565b935093505050612249565b506000905060025b9250929050565b6000816004811115612264576122646129f1565b0361226c5750565b6001816004811115612280576122806129f1565b036122cd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104c3565b60028160048111156122e1576122e16129f1565b0361232e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104c3565b6003816004811115612342576123426129f1565b036123b55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b60048160048111156123c9576123c96129f1565b03610a375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b600060f08083179060ff821690036124575750603092915050565b8060ff1660f10361246b5750603192915050565b8060ff1660f20361247f5750603292915050565b8060ff1660f3036124935750603392915050565b8060ff1660f4036124a75750603492915050565b8060ff1660f5036124bb5750603592915050565b8060ff1660f6036124cf5750603692915050565b8060ff1660f7036124e35750603792915050565b8060ff1660f8036124f75750603892915050565b8060ff1660f90361250b5750603992915050565b8060ff1660fa0361251f5750606192915050565b8060ff1660fb036125335750606292915050565b8060ff1660fc036125475750606392915050565b8060ff1660fd0361255b5750606492915050565b8060ff1660fe0361256f5750606592915050565b8060ff1660ff036113405750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156125ba5750600090506003612692565b8460ff16601b141580156125d257508460ff16601c14155b156125e35750600090506004612692565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612637573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661268b57600060019250925050612692565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816126d160ff86901c601b6129d9565b90506126df87828885612583565b935093505050935093915050565b803563ffffffff8116811461126857600080fd5b60008060006060848603121561271657600080fd5b61271f846126ed565b925061272d602085016126ed565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261277d57600080fd5b813567ffffffffffffffff808211156127985761279861273d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156127de576127de61273d565b816040528381528660208588010111156127f757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561282e57600080fd5b612837856126ed565b9350602085013567ffffffffffffffff81111561285357600080fd5b61285f8782880161276c565b93505061044085018681111561287457600080fd5b9396929550505060409290920191903590565b6000806040838503121561289a57600080fd5b6128a3836126ed565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a3757600080fd5b600080604083850312156128e657600080fd5b6128ef836126ed565b915060208301356128ff816128b1565b809150509250929050565b60006020828403121561291c57600080fd5b813567ffffffffffffffff81111561293357600080fd5b61059d8482850161276c565b60006020828403121561295157600080fd5b8135610424816128b1565b60008060006060848603121561297157600080fd5b61297a846126ed565b95602085013595506040909401359392505050565b6000602082840312156129a157600080fd5b610424826126ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156129ec576129ec6129aa565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612a4657602081850181015186830182015201612a2a565b81811115612a58576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612ac060a0830184612a20565b979650505050505050565b6020815260006104246020830184612a20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612b1f57612b1f6129aa565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b5c57612b5c6129aa565b500290565b600060ff821660ff841680821015612b7b57612b7b6129aa565b90039392505050565b600060ff821660ff84168160ff0481118215151615612ba557612ba56129aa565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611db756fea26469706673582212200899b279b0d431134d4bcadf8747cd7499dbea379b7c3b1ddadf39f5a0f6c6ab64736f6c634300080d0033", +// MessageMetaData contains all meta data concerning the Message contract. +var MessageMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220136bbd8b0d2958472f7ed999406834e4db6caf7b7584da8ea508e848b36d40dd64736f6c634300080d0033", } -// ReplicaManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use ReplicaManagerMetaData.ABI instead. -var ReplicaManagerABI = ReplicaManagerMetaData.ABI - -// Deprecated: Use ReplicaManagerMetaData.Sigs instead. -// ReplicaManagerFuncSigs maps the 4-byte function signature to its string representation. -var ReplicaManagerFuncSigs = ReplicaManagerMetaData.Sigs +// MessageABI is the input ABI used to generate the binding from. +// Deprecated: Use MessageMetaData.ABI instead. +var MessageABI = MessageMetaData.ABI -// ReplicaManagerBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ReplicaManagerMetaData.Bin instead. -var ReplicaManagerBin = ReplicaManagerMetaData.Bin +// MessageBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MessageMetaData.Bin instead. +var MessageBin = MessageMetaData.Bin -// DeployReplicaManager deploys a new Ethereum contract, binding an instance of ReplicaManager to it. -func DeployReplicaManager(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *ReplicaManager, error) { - parsed, err := ReplicaManagerMetaData.GetAbi() +// DeployMessage deploys a new Ethereum contract, binding an instance of Message to it. +func DeployMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Message, error) { + parsed, err := MessageMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -3130,111 +3499,111 @@ func DeployReplicaManager(auth *bind.TransactOpts, backend bind.ContractBackend, return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaManagerBin), backend, _localDomain) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MessageBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ReplicaManager{ReplicaManagerCaller: ReplicaManagerCaller{contract: contract}, ReplicaManagerTransactor: ReplicaManagerTransactor{contract: contract}, ReplicaManagerFilterer: ReplicaManagerFilterer{contract: contract}}, nil + return address, tx, &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil } -// ReplicaManager is an auto generated Go binding around an Ethereum contract. -type ReplicaManager struct { - ReplicaManagerCaller // Read-only binding to the contract - ReplicaManagerTransactor // Write-only binding to the contract - ReplicaManagerFilterer // Log filterer for contract events +// Message is an auto generated Go binding around an Ethereum contract. +type Message struct { + MessageCaller // Read-only binding to the contract + MessageTransactor // Write-only binding to the contract + MessageFilterer // Log filterer for contract events } -// ReplicaManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type ReplicaManagerCaller struct { +// MessageCaller is an auto generated read-only Go binding around an Ethereum contract. +type MessageCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ReplicaManagerTransactor struct { +// MessageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MessageTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ReplicaManagerFilterer struct { +// MessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MessageFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaManagerSession is an auto generated Go binding around an Ethereum contract, +// MessageSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ReplicaManagerSession struct { - Contract *ReplicaManager // Generic contract binding to set the session for +type MessageSession struct { + Contract *Message // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ReplicaManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// MessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ReplicaManagerCallerSession struct { - Contract *ReplicaManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type MessageCallerSession struct { + Contract *MessageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ReplicaManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// MessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ReplicaManagerTransactorSession struct { - Contract *ReplicaManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type MessageTransactorSession struct { + Contract *MessageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ReplicaManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type ReplicaManagerRaw struct { - Contract *ReplicaManager // Generic contract binding to access the raw methods on +// MessageRaw is an auto generated low-level Go binding around an Ethereum contract. +type MessageRaw struct { + Contract *Message // Generic contract binding to access the raw methods on } -// ReplicaManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ReplicaManagerCallerRaw struct { - Contract *ReplicaManagerCaller // Generic read-only contract binding to access the raw methods on +// MessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MessageCallerRaw struct { + Contract *MessageCaller // Generic read-only contract binding to access the raw methods on } -// ReplicaManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ReplicaManagerTransactorRaw struct { - Contract *ReplicaManagerTransactor // Generic write-only contract binding to access the raw methods on +// MessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MessageTransactorRaw struct { + Contract *MessageTransactor // Generic write-only contract binding to access the raw methods on } -// NewReplicaManager creates a new instance of ReplicaManager, bound to a specific deployed contract. -func NewReplicaManager(address common.Address, backend bind.ContractBackend) (*ReplicaManager, error) { - contract, err := bindReplicaManager(address, backend, backend, backend) +// NewMessage creates a new instance of Message, bound to a specific deployed contract. +func NewMessage(address common.Address, backend bind.ContractBackend) (*Message, error) { + contract, err := bindMessage(address, backend, backend, backend) if err != nil { return nil, err } - return &ReplicaManager{ReplicaManagerCaller: ReplicaManagerCaller{contract: contract}, ReplicaManagerTransactor: ReplicaManagerTransactor{contract: contract}, ReplicaManagerFilterer: ReplicaManagerFilterer{contract: contract}}, nil + return &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil } -// NewReplicaManagerCaller creates a new read-only instance of ReplicaManager, bound to a specific deployed contract. -func NewReplicaManagerCaller(address common.Address, caller bind.ContractCaller) (*ReplicaManagerCaller, error) { - contract, err := bindReplicaManager(address, caller, nil, nil) +// NewMessageCaller creates a new read-only instance of Message, bound to a specific deployed contract. +func NewMessageCaller(address common.Address, caller bind.ContractCaller) (*MessageCaller, error) { + contract, err := bindMessage(address, caller, nil, nil) if err != nil { return nil, err } - return &ReplicaManagerCaller{contract: contract}, nil + return &MessageCaller{contract: contract}, nil } -// NewReplicaManagerTransactor creates a new write-only instance of ReplicaManager, bound to a specific deployed contract. -func NewReplicaManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaManagerTransactor, error) { - contract, err := bindReplicaManager(address, nil, transactor, nil) +// NewMessageTransactor creates a new write-only instance of Message, bound to a specific deployed contract. +func NewMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*MessageTransactor, error) { + contract, err := bindMessage(address, nil, transactor, nil) if err != nil { return nil, err } - return &ReplicaManagerTransactor{contract: contract}, nil + return &MessageTransactor{contract: contract}, nil } -// NewReplicaManagerFilterer creates a new log filterer instance of ReplicaManager, bound to a specific deployed contract. -func NewReplicaManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaManagerFilterer, error) { - contract, err := bindReplicaManager(address, nil, nil, filterer) +// NewMessageFilterer creates a new log filterer instance of Message, bound to a specific deployed contract. +func NewMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*MessageFilterer, error) { + contract, err := bindMessage(address, nil, nil, filterer) if err != nil { return nil, err } - return &ReplicaManagerFilterer{contract: contract}, nil + return &MessageFilterer{contract: contract}, nil } -// bindReplicaManager binds a generic wrapper to an already deployed contract. -func bindReplicaManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ReplicaManagerABI)) +// bindMessage binds a generic wrapper to an already deployed contract. +func bindMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MessageABI)) if err != nil { return nil, err } @@ -3245,546 +3614,424 @@ func bindReplicaManager(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ReplicaManager *ReplicaManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaManager.Contract.ReplicaManagerCaller.contract.Call(opts, result, method, params...) +func (_Message *MessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Message.Contract.MessageCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ReplicaManager *ReplicaManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManager.Contract.ReplicaManagerTransactor.contract.Transfer(opts) +func (_Message *MessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Message.Contract.MessageTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ReplicaManager *ReplicaManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaManager.Contract.ReplicaManagerTransactor.contract.Transact(opts, method, params...) +func (_Message *MessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Message.Contract.MessageTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ReplicaManager *ReplicaManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaManager.Contract.contract.Call(opts, result, method, params...) +func (_Message *MessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Message.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ReplicaManager *ReplicaManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManager.Contract.contract.Transfer(opts) +func (_Message *MessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Message.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ReplicaManager *ReplicaManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaManager.Contract.contract.Transact(opts, method, params...) +func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Message.Contract.contract.Transact(opts, method, params...) } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManager *ReplicaManagerCaller) VERSION(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "VERSION") - - if err != nil { - return *new(uint8), err - } +// OwnableUpgradeableMetaData contains all meta data concerning the OwnableUpgradeable contract. +var OwnableUpgradeableMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "f2fde38b": "transferOwnership(address)", + }, +} - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) +// OwnableUpgradeableABI is the input ABI used to generate the binding from. +// Deprecated: Use OwnableUpgradeableMetaData.ABI instead. +var OwnableUpgradeableABI = OwnableUpgradeableMetaData.ABI - return out0, err +// Deprecated: Use OwnableUpgradeableMetaData.Sigs instead. +// OwnableUpgradeableFuncSigs maps the 4-byte function signature to its string representation. +var OwnableUpgradeableFuncSigs = OwnableUpgradeableMetaData.Sigs +// OwnableUpgradeable is an auto generated Go binding around an Ethereum contract. +type OwnableUpgradeable struct { + OwnableUpgradeableCaller // Read-only binding to the contract + OwnableUpgradeableTransactor // Write-only binding to the contract + OwnableUpgradeableFilterer // Log filterer for contract events } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManager *ReplicaManagerSession) VERSION() (uint8, error) { - return _ReplicaManager.Contract.VERSION(&_ReplicaManager.CallOpts) +// OwnableUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. +type OwnableUpgradeableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManager *ReplicaManagerCallerSession) VERSION() (uint8, error) { - return _ReplicaManager.Contract.VERSION(&_ReplicaManager.CallOpts) +// OwnableUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type OwnableUpgradeableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. -// -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManager *ReplicaManagerCaller) AcceptableRoot(opts *bind.CallOpts, _remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "acceptableRoot", _remoteDomain, _optimisticSeconds, _root) - - if err != nil { - return *new(bool), err - } +// OwnableUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OwnableUpgradeableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) +// OwnableUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type OwnableUpgradeableSession struct { + Contract *OwnableUpgradeable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - return out0, err +// OwnableUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type OwnableUpgradeableCallerSession struct { + Contract *OwnableUpgradeableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} +// OwnableUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type OwnableUpgradeableTransactorSession struct { + Contract *OwnableUpgradeableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. -// -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManager *ReplicaManagerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { - return _ReplicaManager.Contract.AcceptableRoot(&_ReplicaManager.CallOpts, _remoteDomain, _optimisticSeconds, _root) +// OwnableUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. +type OwnableUpgradeableRaw struct { + Contract *OwnableUpgradeable // Generic contract binding to access the raw methods on } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. -// -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManager *ReplicaManagerCallerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { - return _ReplicaManager.Contract.AcceptableRoot(&_ReplicaManager.CallOpts, _remoteDomain, _optimisticSeconds, _root) +// OwnableUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OwnableUpgradeableCallerRaw struct { + Contract *OwnableUpgradeableCaller // Generic read-only contract binding to access the raw methods on } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. -// -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaConfirmedAt(opts *bind.CallOpts, _remoteDomain uint32, _root [32]byte) (*big.Int, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaConfirmedAt", _remoteDomain, _root) +// OwnableUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OwnableUpgradeableTransactorRaw struct { + Contract *OwnableUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +} +// NewOwnableUpgradeable creates a new instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeable(address common.Address, backend bind.ContractBackend) (*OwnableUpgradeable, error) { + contract, err := bindOwnableUpgradeable(address, backend, backend, backend) if err != nil { - return *new(*big.Int), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - + return &OwnableUpgradeable{OwnableUpgradeableCaller: OwnableUpgradeableCaller{contract: contract}, OwnableUpgradeableTransactor: OwnableUpgradeableTransactor{contract: contract}, OwnableUpgradeableFilterer: OwnableUpgradeableFilterer{contract: contract}}, nil } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. -// -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { - return _ReplicaManager.Contract.ActiveReplicaConfirmedAt(&_ReplicaManager.CallOpts, _remoteDomain, _root) +// NewOwnableUpgradeableCaller creates a new read-only instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*OwnableUpgradeableCaller, error) { + contract, err := bindOwnableUpgradeable(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OwnableUpgradeableCaller{contract: contract}, nil } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. -// -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { - return _ReplicaManager.Contract.ActiveReplicaConfirmedAt(&_ReplicaManager.CallOpts, _remoteDomain, _root) +// NewOwnableUpgradeableTransactor creates a new write-only instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableUpgradeableTransactor, error) { + contract, err := bindOwnableUpgradeable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OwnableUpgradeableTransactor{contract: contract}, nil } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. -// -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaMessageStatus(opts *bind.CallOpts, _remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaMessageStatus", _remoteDomain, _messageId) +// NewOwnableUpgradeableFilterer creates a new log filterer instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableUpgradeableFilterer, error) { + contract, err := bindOwnableUpgradeable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OwnableUpgradeableFilterer{contract: contract}, nil +} +// bindOwnableUpgradeable binds a generic wrapper to an already deployed contract. +func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(OwnableUpgradeableABI)) if err != nil { - return *new([32]byte), err + return nil, err } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OwnableUpgradeable.Contract.OwnableUpgradeableCaller.contract.Call(opts, result, method, params...) +} - return out0, err +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transfer(opts) +} +// Transact invokes the (paid) contract method with params as input values. +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transact(opts, method, params...) } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. -// -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - return _ReplicaManager.Contract.ActiveReplicaMessageStatus(&_ReplicaManager.CallOpts, _remoteDomain, _messageId) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OwnableUpgradeable *OwnableUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OwnableUpgradeable.Contract.contract.Call(opts, result, method, params...) } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. -// -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - return _ReplicaManager.Contract.ActiveReplicaMessageStatus(&_ReplicaManager.CallOpts, _remoteDomain, _messageId) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.contract.Transfer(opts) } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// Transact invokes the (paid) contract method with params as input values. +func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.contract.Transact(opts, method, params...) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaNonce(opts *bind.CallOpts, _remoteDomain uint32) (uint32, error) { +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaNonce", _remoteDomain) + err := _OwnableUpgradeable.contract.Call(opts, &out, "owner") if err != nil { - return *new(uint32), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { - return _ReplicaManager.Contract.ActiveReplicaNonce(&_ReplicaManager.CallOpts, _remoteDomain) +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableSession) Owner() (common.Address, error) { + return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { - return _ReplicaManager.Contract.ActiveReplicaNonce(&_ReplicaManager.CallOpts, _remoteDomain) +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableCallerSession) Owner() (common.Address, error) { + return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManager *ReplicaManagerCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "localDomain") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.contract.Transact(opts, "renounceOwnership") } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManager *ReplicaManagerSession) LocalDomain() (uint32, error) { - return _ReplicaManager.Contract.LocalDomain(&_ReplicaManager.CallOpts) +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManager *ReplicaManagerCallerSession) LocalDomain() (uint32, error) { - return _ReplicaManager.Contract.LocalDomain(&_ReplicaManager.CallOpts) +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function owner() view returns(address) -func (_ReplicaManager *ReplicaManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function owner() view returns(address) -func (_ReplicaManager *ReplicaManagerSession) Owner() (common.Address, error) { - return _ReplicaManager.Contract.Owner(&_ReplicaManager.CallOpts) +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function owner() view returns(address) -func (_ReplicaManager *ReplicaManagerCallerSession) Owner() (common.Address, error) { - return _ReplicaManager.Contract.Owner(&_ReplicaManager.CallOpts) +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManager *ReplicaManagerCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "systemMessenger") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} +// OwnableUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the OwnableUpgradeable contract. +type OwnableUpgradeableInitializedIterator struct { + Event *OwnableUpgradeableInitialized // Event containing the contract specifics and raw log -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManager *ReplicaManagerSession) SystemMessenger() (common.Address, error) { - return _ReplicaManager.Contract.SystemMessenger(&_ReplicaManager.CallOpts) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManager *ReplicaManagerCallerSession) SystemMessenger() (common.Address, error) { - return _ReplicaManager.Contract.SystemMessenger(&_ReplicaManager.CallOpts) + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_ReplicaManager *ReplicaManagerCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManager.contract.Call(opts, &out, "updater") - - if err != nil { - return *new(common.Address), err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OwnableUpgradeableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_ReplicaManager *ReplicaManagerSession) Updater() (common.Address, error) { - return _ReplicaManager.Contract.Updater(&_ReplicaManager.CallOpts) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OwnableUpgradeableInitializedIterator) Error() error { + return it.fail } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_ReplicaManager *ReplicaManagerCallerSession) Updater() (common.Address, error) { - return _ReplicaManager.Contract.Updater(&_ReplicaManager.CallOpts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OwnableUpgradeableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. -// -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManager *ReplicaManagerTransactor) Initialize(opts *bind.TransactOpts, _remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "initialize", _remoteDomain, _updater) +// OwnableUpgradeableInitialized represents a Initialized event raised by the OwnableUpgradeable contract. +type OwnableUpgradeableInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManager *ReplicaManagerSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.Initialize(&_ReplicaManager.TransactOpts, _remoteDomain, _updater) -} +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*OwnableUpgradeableInitializedIterator, error) { -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. -// -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.Initialize(&_ReplicaManager.TransactOpts, _remoteDomain, _updater) + logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &OwnableUpgradeableInitializedIterator{contract: _OwnableUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function process(bytes _message) returns() -func (_ReplicaManager *ReplicaManagerTransactor) Process(opts *bind.TransactOpts, _message []byte) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "process", _message) -} +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableInitialized) (event.Subscription, error) { -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. -// -// Solidity: function process(bytes _message) returns() -func (_ReplicaManager *ReplicaManagerSession) Process(_message []byte) (*types.Transaction, error) { - return _ReplicaManager.Contract.Process(&_ReplicaManager.TransactOpts, _message) -} + logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OwnableUpgradeableInitialized) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. -// -// Solidity: function process(bytes _message) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) Process(_message []byte) (*types.Transaction, error) { - return _ReplicaManager.Contract.Process(&_ReplicaManager.TransactOpts, _message) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManager *ReplicaManagerTransactor) Prove(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "prove", _remoteDomain, _message, _proof, _index) +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseInitialized(log types.Log) (*OwnableUpgradeableInitialized, error) { + event := new(OwnableUpgradeableInitialized) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. -// -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManager *ReplicaManagerSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.Prove(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) -} +// OwnableUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the OwnableUpgradeable contract. +type OwnableUpgradeableOwnershipTransferredIterator struct { + Event *OwnableUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. -// -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManager *ReplicaManagerTransactorSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.Prove(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. -// -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManager *ReplicaManagerTransactor) ProveAndProcess(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "proveAndProcess", _remoteDomain, _message, _proof, _index) -} - -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. -// -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManager *ReplicaManagerSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.ProveAndProcess(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) -} - -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. -// -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.ProveAndProcess(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManager *ReplicaManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManager *ReplicaManagerSession) RenounceOwnership() (*types.Transaction, error) { - return _ReplicaManager.Contract.RenounceOwnership(&_ReplicaManager.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _ReplicaManager.Contract.RenounceOwnership(&_ReplicaManager.TransactOpts) -} - -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManager *ReplicaManagerTransactor) SetConfirmation(opts *bind.TransactOpts, _remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "setConfirmation", _remoteDomain, _root, _confirmAt) -} - -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManager *ReplicaManagerSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetConfirmation(&_ReplicaManager.TransactOpts, _remoteDomain, _root, _confirmAt) -} - -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetConfirmation(&_ReplicaManager.TransactOpts, _remoteDomain, _root, _confirmAt) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManager *ReplicaManagerTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "setSystemMessenger", _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManager *ReplicaManagerSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetSystemMessenger(&_ReplicaManager.TransactOpts, _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetSystemMessenger(&_ReplicaManager.TransactOpts, _systemMessenger) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManager *ReplicaManagerTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "setUpdater", _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManager *ReplicaManagerSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetUpdater(&_ReplicaManager.TransactOpts, _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.SetUpdater(&_ReplicaManager.TransactOpts, _updater) -} - -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManager *ReplicaManagerTransactor) SubmitAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "submitAttestation", _attestation) -} - -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManager *ReplicaManagerSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { - return _ReplicaManager.Contract.SubmitAttestation(&_ReplicaManager.TransactOpts, _attestation) -} - -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { - return _ReplicaManager.Contract.SubmitAttestation(&_ReplicaManager.TransactOpts, _attestation) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManager *ReplicaManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManager.contract.Transact(opts, "transferOwnership", newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManager *ReplicaManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.TransferOwnership(&_ReplicaManager.TransactOpts, newOwner) -} - -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManager *ReplicaManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManager.Contract.TransferOwnership(&_ReplicaManager.TransactOpts, newOwner) -} - -// ReplicaManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ReplicaManager contract. -type ReplicaManagerInitializedIterator struct { - Event *ReplicaManagerInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerInitializedIterator) Next() bool { +func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -3793,7 +4040,7 @@ func (it *ReplicaManagerInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerInitialized) + it.Event = new(OwnableUpgradeableOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3808,7 +4055,7 @@ func (it *ReplicaManagerInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerInitialized) + it.Event = new(OwnableUpgradeableOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -3824,41 +4071,60 @@ func (it *ReplicaManagerInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerInitializedIterator) Error() error { +func (it *OwnableUpgradeableOwnershipTransferredIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerInitializedIterator) Close() error { +func (it *OwnableUpgradeableOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerInitialized represents a Initialized event raised by the ReplicaManager contract. -type ReplicaManagerInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// OwnableUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the OwnableUpgradeable contract. +type OwnableUpgradeableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Initialized(uint8 version) -func (_ReplicaManager *ReplicaManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ReplicaManagerInitializedIterator, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableUpgradeableOwnershipTransferredIterator, error) { - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "Initialized") + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } - return &ReplicaManagerInitializedIterator{contract: _ReplicaManager.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &OwnableUpgradeableOwnershipTransferredIterator{contract: _OwnableUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Initialized(uint8 version) -func (_ReplicaManager *ReplicaManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ReplicaManagerInitialized) (event.Subscription, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Initialized") + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } @@ -3868,8 +4134,8 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchInitialized(opts *bind.Watch select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerInitialized) - if err := _ReplicaManager.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(OwnableUpgradeableOwnershipTransferred) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -3890,252 +4156,1966 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchInitialized(opts *bind.Watch }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Initialized(uint8 version) -func (_ReplicaManager *ReplicaManagerFilterer) ParseInitialized(log types.Log) (*ReplicaManagerInitialized, error) { - event := new(ReplicaManagerInitialized) - if err := _ReplicaManager.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableUpgradeableOwnershipTransferred, error) { + event := new(OwnableUpgradeableOwnershipTransferred) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the ReplicaManager contract. -type ReplicaManagerNewUpdaterIterator struct { - Event *ReplicaManagerNewUpdater // Event containing the contract specifics and raw log +// ReplicaLibMetaData contains all meta data concerning the ReplicaLib contract. +var ReplicaLibMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"MESSAGE_STATUS_NONE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MESSAGE_STATUS_PROCESSED\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "b0075818": "MESSAGE_STATUS_NONE()", + "643d8086": "MESSAGE_STATUS_PROCESSED()", + }, + Bin: "0x6098610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212205c7eae674429e9cf7baf8c5c1a192fbb52dda29281abdea12a1ef394e035993764736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// ReplicaLibABI is the input ABI used to generate the binding from. +// Deprecated: Use ReplicaLibMetaData.ABI instead. +var ReplicaLibABI = ReplicaLibMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// Deprecated: Use ReplicaLibMetaData.Sigs instead. +// ReplicaLibFuncSigs maps the 4-byte function signature to its string representation. +var ReplicaLibFuncSigs = ReplicaLibMetaData.Sigs -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// ReplicaLibBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ReplicaLibMetaData.Bin instead. +var ReplicaLibBin = ReplicaLibMetaData.Bin - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// DeployReplicaLib deploys a new Ethereum contract, binding an instance of ReplicaLib to it. +func DeployReplicaLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ReplicaLib, error) { + parsed, err := ReplicaLibMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaLibBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } + return address, tx, &ReplicaLib{ReplicaLibCaller: ReplicaLibCaller{contract: contract}, ReplicaLibTransactor: ReplicaLibTransactor{contract: contract}, ReplicaLibFilterer: ReplicaLibFilterer{contract: contract}}, nil } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerNewUpdaterIterator) Error() error { - return it.fail +// ReplicaLib is an auto generated Go binding around an Ethereum contract. +type ReplicaLib struct { + ReplicaLibCaller // Read-only binding to the contract + ReplicaLibTransactor // Write-only binding to the contract + ReplicaLibFilterer // Log filterer for contract events } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ReplicaManagerNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// ReplicaLibCaller is an auto generated read-only Go binding around an Ethereum contract. +type ReplicaLibCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaManagerNewUpdater represents a NewUpdater event raised by the ReplicaManager contract. -type ReplicaManagerNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// ReplicaLibTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ReplicaLibTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManager *ReplicaManagerFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*ReplicaManagerNewUpdaterIterator, error) { +// ReplicaLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ReplicaLibFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaLibSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ReplicaLibSession struct { + Contract *ReplicaLib // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ReplicaLibCallerSession struct { + Contract *ReplicaLibCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ReplicaLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ReplicaLibTransactorSession struct { + Contract *ReplicaLibTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaLibRaw is an auto generated low-level Go binding around an Ethereum contract. +type ReplicaLibRaw struct { + Contract *ReplicaLib // Generic contract binding to access the raw methods on +} + +// ReplicaLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ReplicaLibCallerRaw struct { + Contract *ReplicaLibCaller // Generic read-only contract binding to access the raw methods on +} + +// ReplicaLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ReplicaLibTransactorRaw struct { + Contract *ReplicaLibTransactor // Generic write-only contract binding to access the raw methods on +} - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "NewUpdater") +// NewReplicaLib creates a new instance of ReplicaLib, bound to a specific deployed contract. +func NewReplicaLib(address common.Address, backend bind.ContractBackend) (*ReplicaLib, error) { + contract, err := bindReplicaLib(address, backend, backend, backend) if err != nil { return nil, err } - return &ReplicaManagerNewUpdaterIterator{contract: _ReplicaManager.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &ReplicaLib{ReplicaLibCaller: ReplicaLibCaller{contract: contract}, ReplicaLibTransactor: ReplicaLibTransactor{contract: contract}, ReplicaLibFilterer: ReplicaLibFilterer{contract: contract}}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManager *ReplicaManagerFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *ReplicaManagerNewUpdater) (event.Subscription, error) { - - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "NewUpdater") +// NewReplicaLibCaller creates a new read-only instance of ReplicaLib, bound to a specific deployed contract. +func NewReplicaLibCaller(address common.Address, caller bind.ContractCaller) (*ReplicaLibCaller, error) { + contract, err := bindReplicaLib(address, caller, nil, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerNewUpdater) - if err := _ReplicaManager.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &ReplicaLibCaller{contract: contract}, nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManager *ReplicaManagerFilterer) ParseNewUpdater(log types.Log) (*ReplicaManagerNewUpdater, error) { - event := new(ReplicaManagerNewUpdater) - if err := _ReplicaManager.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// NewReplicaLibTransactor creates a new write-only instance of ReplicaLib, bound to a specific deployed contract. +func NewReplicaLibTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaLibTransactor, error) { + contract, err := bindReplicaLib(address, nil, transactor, nil) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &ReplicaLibTransactor{contract: contract}, nil } -// ReplicaManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ReplicaManager contract. -type ReplicaManagerOwnershipTransferredIterator struct { - Event *ReplicaManagerOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// NewReplicaLibFilterer creates a new log filterer instance of ReplicaLib, bound to a specific deployed contract. +func NewReplicaLibFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaLibFilterer, error) { + contract, err := bindReplicaLib(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ReplicaLibFilterer{contract: contract}, nil } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// bindReplicaLib binds a generic wrapper to an already deployed contract. +func bindReplicaLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ReplicaLibABI)) + if err != nil { + return nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaLib *ReplicaLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaLib.Contract.ReplicaLibCaller.contract.Call(opts, result, method, params...) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaLib *ReplicaLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaLib.Contract.ReplicaLibTransactor.contract.Transfer(opts) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerOwnershipTransferredIterator) Error() error { - return it.fail +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaLib *ReplicaLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaLib.Contract.ReplicaLibTransactor.contract.Transact(opts, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ReplicaManagerOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaLib *ReplicaLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaLib.Contract.contract.Call(opts, result, method, params...) } -// ReplicaManagerOwnershipTransferred represents a OwnershipTransferred event raised by the ReplicaManager contract. -type ReplicaManagerOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaLib *ReplicaLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaLib.Contract.contract.Transfer(opts) } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_ReplicaManager *ReplicaManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ReplicaManagerOwnershipTransferredIterator, error) { +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaLib *ReplicaLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaLib.Contract.contract.Transact(opts, method, params...) +} - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. +// +// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) +func (_ReplicaLib *ReplicaLibCaller) MESSAGESTATUSNONE(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ReplicaLib.contract.Call(opts, &out, "MESSAGE_STATUS_NONE") - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { - return nil, err + return *new([32]byte), err } - return &ReplicaManagerOwnershipTransferredIterator{contract: _ReplicaManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_ReplicaManager *ReplicaManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ReplicaManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. +// +// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) +func (_ReplicaLib *ReplicaLibSession) MESSAGESTATUSNONE() ([32]byte, error) { + return _ReplicaLib.Contract.MESSAGESTATUSNONE(&_ReplicaLib.CallOpts) +} + +// MESSAGESTATUSNONE is a free data retrieval call binding the contract method 0xb0075818. +// +// Solidity: function MESSAGE_STATUS_NONE() view returns(bytes32) +func (_ReplicaLib *ReplicaLibCallerSession) MESSAGESTATUSNONE() ([32]byte, error) { + return _ReplicaLib.Contract.MESSAGESTATUSNONE(&_ReplicaLib.CallOpts) +} + +// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. +// +// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) +func (_ReplicaLib *ReplicaLibCaller) MESSAGESTATUSPROCESSED(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ReplicaLib.contract.Call(opts, &out, "MESSAGE_STATUS_PROCESSED") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. +// +// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) +func (_ReplicaLib *ReplicaLibSession) MESSAGESTATUSPROCESSED() ([32]byte, error) { + return _ReplicaLib.Contract.MESSAGESTATUSPROCESSED(&_ReplicaLib.CallOpts) +} + +// MESSAGESTATUSPROCESSED is a free data retrieval call binding the contract method 0x643d8086. +// +// Solidity: function MESSAGE_STATUS_PROCESSED() view returns(bytes32) +func (_ReplicaLib *ReplicaLibCallerSession) MESSAGESTATUSPROCESSED() ([32]byte, error) { + return _ReplicaLib.Contract.MESSAGESTATUSPROCESSED(&_ReplicaLib.CallOpts) +} + +// ReplicaManagerMetaData contains all meta data concerning the ReplicaManager contract. +var ReplicaManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"AttestationAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "ffa1ad74": "VERSION()", + "15a046aa": "acceptableRoot(uint32,uint32,bytes32)", + "7dfdba28": "activeReplicaConfirmedAt(uint32,bytes32)", + "63415514": "activeReplicaMessageStatus(uint32,bytes32)", + "b65672d3": "activeReplicaNonce(uint32)", + "9fe03fa2": "allGuards()", + "629ddf69": "getGuard(uint256)", + "246c2449": "guardsAmount()", + "8624c35c": "initialize(uint32,address)", + "8d3638f4": "localDomain()", + "8da5cb5b": "owner()", + "928bc4b2": "process(bytes)", + "4f63be3f": "prove(uint32,bytes,bytes32[32],uint256)", + "68705275": "proveAndProcess(uint32,bytes,bytes32[32],uint256)", + "715018a6": "renounceOwnership()", + "9df7d36d": "setConfirmation(uint32,bytes32,uint256)", + "b7bc563e": "setSystemMessenger(address)", + "61bc3111": "setUpdater(uint32,address)", + "f646a512": "submitAttestation(bytes)", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + }, + Bin: "0x60a06040523480156200001157600080fd5b5060405162002f5238038062002f52833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612eb66200009c600039600081816102cf015281816109240152610f310152612eb66000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638d3638f4116100d8578063b65672d31161008c578063f2fde38b11610066578063f2fde38b146103c8578063f646a512146103db578063ffa1ad74146103ee57600080fd5b8063b65672d31461035f578063b7bc563e14610395578063ccbdf9c9146103a857600080fd5b8063928bc4b2116100bd578063928bc4b2146103245780639df7d36d146103375780639fe03fa21461034a57600080fd5b80638d3638f4146102ca5780638da5cb5b1461030657600080fd5b8063634155141161012f578063715018a611610114578063715018a61461026e5780637dfdba28146102765780638624c35c146102b757600080fd5b8063634155141461021a578063687052751461025b57600080fd5b80634f63be3f116101605780634f63be3f146101ba57806361bc3111146101cd578063629ddf69146101e257600080fd5b806315a046aa1461017c578063246c2449146101a4575b600080fd5b61018f61018a366004612824565b610408565b60405190151581526020015b60405180910390f35b6101ac610465565b60405190815260200161019b565b61018f6101c836600461293a565b610476565b6101e06101db3660046129cc565b6105f0565b005b6101f56101f0366004612a03565b610666565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101ac610228366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b6101e061026936600461293a565b610679565b6101e06106e0565b6101ac610284366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b6101e06102c53660046129cc565b610749565b6102f17f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019b565b60335473ffffffffffffffffffffffffffffffffffffffff166101f5565b6101e0610332366004612a46565b6108cb565b6101e0610345366004612a7b565b610c67565b610352610d5b565b60405161019b9190612aae565b6102f161036d366004612b08565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b6101e06103a3366004612b23565b610d67565b6065546101f59073ffffffffffffffffffffffffffffffffffffffff1681565b6101e06103d6366004612b23565b610e15565b6101e06103e9366004612a46565b610f0e565b6103f6600081565b60405160ff909116815260200161019b565b63ffffffff8316600090815260ce6020908152604080832054835260cd825280832084845260010190915281205480820361044757600091505061045e565b61045763ffffffff851682612b6f565b4210159150505b9392505050565b600061047160986110e9565b905090565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff1660028111156104c5576104c5612b87565b146105175760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105755760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e6500000000000000000000000000604482015260640161050e565b60006105ab8387602080602002604051908101604052809291908260208002808284376000920191909152508991506110f39050565b6000818152600184016020526040902054909150156105e05760009283526002919091016020526040909120555060016105e8565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106575760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b6106618282611199565b505050565b6000610673609883611296565b92915050565b61068584848484610476565b6106d15760405162461bcd60e51b815260206004820152600660248201527f2170726f76650000000000000000000000000000000000000000000000000000604482015260640161050e565b6106da836108cb565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b565b600061075560016112a2565b9050801561078a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6107926113f9565b61079c8383611199565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561084e8360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561066157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60006108d68261147e565b905060006108e962ffffff19831661148c565b905060006108fc62ffffff1983166114cc565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661095362ffffff1985166114f6565b63ffffffff16146109a65760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e0000000000000000000000000000000000000000604482015260640161050e565b60006109b762ffffff198616611517565b60008181526002840160205260409020549091506109d481611574565b610a205760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f636573736564000000000000000000000000604482015260640161050e565b610a3984610a3362ffffff198816611588565b83610408565b610a855760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e64730000000000000000000000000000604482015260640161050e565b60cb5460ff16600114610ada5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e7400000000000000000000000000000000000000000000604482015260640161050e565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b17610b1462ffffff1988166115a9565b50565b6000828152600284016020526040812060019055610b42610b3d62ffffff1988166115e0565b611601565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b7062ffffff198a16611643565b610b7f62ffffff198b16611664565b600087815260018a016020526040902054610bad610ba262ffffff198f16611685565b62ffffff19166116c4565b6040518663ffffffff1660e01b8152600401610bcd959493929190612c21565b600060405180830381600087803b158015610be757600080fd5b505af1158015610bfb573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610d119083908690869061171716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b6060610471609861172b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e7c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b73ffffffffffffffffffffffffffffffffffffffff8116610f055760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161050e565b610b1481611738565b6000610f19826117af565b9150506000610f2d8262ffffff19166118e9565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610faa5760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e00000000604482015260640161050e565b6000610fbb62ffffff1984166118fd565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116110365760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e7420737461746500604482015260640161050e565b600061104762ffffff198616611911565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6110cc610ba28a62ffffff1916611926565b6040516110d99190612c61565b60405180910390a4505050505050565b6000610673825490565b8260005b602081101561119157600183821c16600085836020811061111a5761111a612c74565b602002015190508160010361115a576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611187565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b50506001016110f7565b509392505050565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156111dd57506000610673565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b600061045e8383611959565b60008054610100900460ff161561133f578160ff1660011480156112c55750303b155b6113375760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b506000919050565b60005460ff8084169116106113bc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114765760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b610747611983565b600061067382610539611a09565b6000816114a162ffffff198216610539611a2d565b506114c3836114b1856001611b2e565b6114bc866002611b2e565b6001611b60565b91505b50919050565b6000816114e260015b62ffffff19831690611a2d565b506114c362ffffff19841660026004611b7f565b60008161150360016114d5565b506114c362ffffff198416602a6004611b7f565b6000806115328360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061155c8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906106735750506001141590565b60008161159560016114d5565b506114c362ffffff198416604e6004611b7f565b6000816115be62ffffff198216610539611a2d565b506114c3836115ce856002611b2e565b6115d9866003611b2e565b6002611b60565b6000816115ed60016114d5565b506114c362ffffff198416602e6020611baf565b600074010000000000000000000000000000000000000000820161163d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b81610673565b60008161165060016114d5565b506114c362ffffff19841660266004611b7f565b60008161167160016114d5565b506114c362ffffff19841660066020611baf565b60008161169a62ffffff198216610539611a2d565b506114c3836116aa856003611b2e565b601886901c6bffffffffffffffffffffffff166003611b60565b60606000806116e18460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117068483602001611d6d565b508181016020016040529052919050565b600091825260019092016020526040902055565b6060600061045e83611f12565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806117bc8382611a09565b905060286bffffffffffffffffffffffff601883901c16116118205760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161050e565b61184961183262ffffff198316611f6e565b611844610ba262ffffff198516611926565b611f83565b915061189861185d62ffffff1983166118e9565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6118e45760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161050e565b915091565b600061067362ffffff198316826004611b7f565b600061067362ffffff198316600480611b7f565b600061067362ffffff19831660086020611baf565b6000610673602861194981601886901c6bffffffffffffffffffffffff16612ca3565b62ffffff19851691906000611ffa565b600082600001828154811061197057611970612c74565b9060005260206000200154905092915050565b600054610100900460ff16611a005760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b61074733611738565b815160009060208401611a2464ffffffffff85168284612070565b95945050505050565b6000611a3983836120b7565b611b27576000611a58611a4c8560d81c90565b64ffffffffff166120da565b9150506000611a6d8464ffffffffff166120da565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161050e9190612c61565b5090919050565b600061045e6002836004811115611b4757611b47612b87565b611b519190612cba565b62ffffff198516906002611b7f565b6000611a2484611b708186612ca3565b62ffffff198816919085611ffa565b6000611b8c826020612cf7565b611b97906008612d1a565b60ff16611ba5858585611baf565b901c949350505050565b60008160ff16600003611bc45750600061045e565b611bdc8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611bf760ff841685612b6f565b1115611c6f57611c56611c188560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611c3e8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166121c4565b60405162461bcd60e51b815260040161050e9190612c61565b60208260ff161115611ce95760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161050e565b600882026000611d078660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611dea5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161050e565b611df383612232565b611e655760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161050e565b6000611e7f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611ea98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611ece5760206060fd5b8285848460045afa50611f08611ee48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611f6257602002820191906000526020600020905b815481526020019060010190808311611f4e575b50505050509050919050565b600061067362ffffff19831682602881611ffa565b600080611f9562ffffff198516611517565b9050611fee816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506105e8818461226f565b6000806120158660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061202e8661228b565b846120398784612b6f565b6120439190612b6f565b11156120565762ffffff199150506105e8565b6120608582612b6f565b9050611f088364ffffffffff1682865b60008061207d8385612b6f565b905060405181111561208d575060005b806000036120a25762ffffff1991505061045e565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166120cb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561214d5760006120f9826008612d1a565b60ff1685901c905061210a816122d3565b61ffff16841793508160ff1660101461212557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016120e0565b50600f5b60ff8160ff1610156121be57600061216a826008612d1a565b60ff1685901c905061217b816122d3565b61ffff16831792508160ff1660001461219657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612151565b50915091565b606060006121d1866120da565b91505060006121df866120da565b91505060006121ed866120da565b91505060006121fb866120da565b915050838383836040516020016122159493929190612d43565b604051602081830303815290604052945050505050949350505050565b600061223e8260d81c90565b64ffffffffff1664ffffffffff0361225857506000919050565b60006122638361228b565b60405110199392505050565b600080600061227e8585612305565b9150915061119181612373565b60006122a58260181c6bffffffffffffffffffffffff1690565b6122bd8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006122e560048360ff16901c61255f565b60ff1661ffff919091161760081b6122fc8261255f565b60ff1617919050565b600080825160410361233b5760208301516040840151606085015160001a61232f878285856126a6565b9450945050505061236c565b825160400361236457602083015160408401516123598683836127be565b93509350505061236c565b506000905060025b9250929050565b600081600481111561238757612387612b87565b0361238f5750565b60018160048111156123a3576123a3612b87565b036123f05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161050e565b600281600481111561240457612404612b87565b036124515760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161050e565b600381600481111561246557612465612b87565b036124d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b60048160048111156124ec576124ec612b87565b03610b145760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b600060f08083179060ff8216900361257a5750603092915050565b8060ff1660f10361258e5750603192915050565b8060ff1660f2036125a25750603292915050565b8060ff1660f3036125b65750603392915050565b8060ff1660f4036125ca5750603492915050565b8060ff1660f5036125de5750603592915050565b8060ff1660f6036125f25750603692915050565b8060ff1660f7036126065750603792915050565b8060ff1660f80361261a5750603892915050565b8060ff1660f90361262e5750603992915050565b8060ff1660fa036126425750606192915050565b8060ff1660fb036126565750606292915050565b8060ff1660fc0361266a5750606392915050565b8060ff1660fd0361267e5750606492915050565b8060ff1660fe036126925750606592915050565b8060ff1660ff036114c65750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126dd57506000905060036127b5565b8460ff16601b141580156126f557508460ff16601c14155b1561270657506000905060046127b5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561275a573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166127ae576000600192509250506127b5565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816127f460ff86901c601b612b6f565b9050612802878288856126a6565b935093505050935093915050565b803563ffffffff811681146113f457600080fd5b60008060006060848603121561283957600080fd5b61284284612810565b925061285060208501612810565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126128a057600080fd5b813567ffffffffffffffff808211156128bb576128bb612860565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561290157612901612860565b8160405283815286602085880101111561291a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561295157600080fd5b61295a85612810565b9350602085013567ffffffffffffffff81111561297657600080fd5b6129828782880161288f565b93505061044085018681111561299757600080fd5b9396929550505060409290920191903590565b73ffffffffffffffffffffffffffffffffffffffff81168114610b1457600080fd5b600080604083850312156129df57600080fd5b6129e883612810565b915060208301356129f8816129aa565b809150509250929050565b600060208284031215612a1557600080fd5b5035919050565b60008060408385031215612a2f57600080fd5b612a3883612810565b946020939093013593505050565b600060208284031215612a5857600080fd5b813567ffffffffffffffff811115612a6f57600080fd5b6105e88482850161288f565b600080600060608486031215612a9057600080fd5b612a9984612810565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612afc57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612aca565b50909695505050505050565b600060208284031215612b1a57600080fd5b61045e82612810565b600060208284031215612b3557600080fd5b813561045e816129aa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612b8257612b82612b40565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612bdc57602081850181015186830182015201612bc0565b81811115612bee576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612c5660a0830184612bb6565b979650505050505050565b60208152600061045e6020830184612bb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612cb557612cb5612b40565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612cf257612cf2612b40565b500290565b600060ff821660ff841680821015612d1157612d11612b40565b90039392505050565b600060ff821660ff84168160ff0481118215151615612d3b57612d3b612b40565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611f0856fea264697066735822122091ca50ae4e0182c9cc516c0057abe5efe055e56b91b8e4ec3918ea89f4487f6c64736f6c634300080d0033", +} + +// ReplicaManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ReplicaManagerMetaData.ABI instead. +var ReplicaManagerABI = ReplicaManagerMetaData.ABI + +// Deprecated: Use ReplicaManagerMetaData.Sigs instead. +// ReplicaManagerFuncSigs maps the 4-byte function signature to its string representation. +var ReplicaManagerFuncSigs = ReplicaManagerMetaData.Sigs + +// ReplicaManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ReplicaManagerMetaData.Bin instead. +var ReplicaManagerBin = ReplicaManagerMetaData.Bin + +// DeployReplicaManager deploys a new Ethereum contract, binding an instance of ReplicaManager to it. +func DeployReplicaManager(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *ReplicaManager, error) { + parsed, err := ReplicaManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaManagerBin), backend, _localDomain) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ReplicaManager{ReplicaManagerCaller: ReplicaManagerCaller{contract: contract}, ReplicaManagerTransactor: ReplicaManagerTransactor{contract: contract}, ReplicaManagerFilterer: ReplicaManagerFilterer{contract: contract}}, nil +} + +// ReplicaManager is an auto generated Go binding around an Ethereum contract. +type ReplicaManager struct { + ReplicaManagerCaller // Read-only binding to the contract + ReplicaManagerTransactor // Write-only binding to the contract + ReplicaManagerFilterer // Log filterer for contract events +} + +// ReplicaManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ReplicaManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ReplicaManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ReplicaManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ReplicaManagerSession struct { + Contract *ReplicaManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ReplicaManagerCallerSession struct { + Contract *ReplicaManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ReplicaManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ReplicaManagerTransactorSession struct { + Contract *ReplicaManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ReplicaManagerRaw struct { + Contract *ReplicaManager // Generic contract binding to access the raw methods on +} + +// ReplicaManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ReplicaManagerCallerRaw struct { + Contract *ReplicaManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ReplicaManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ReplicaManagerTransactorRaw struct { + Contract *ReplicaManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewReplicaManager creates a new instance of ReplicaManager, bound to a specific deployed contract. +func NewReplicaManager(address common.Address, backend bind.ContractBackend) (*ReplicaManager, error) { + contract, err := bindReplicaManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ReplicaManager{ReplicaManagerCaller: ReplicaManagerCaller{contract: contract}, ReplicaManagerTransactor: ReplicaManagerTransactor{contract: contract}, ReplicaManagerFilterer: ReplicaManagerFilterer{contract: contract}}, nil +} + +// NewReplicaManagerCaller creates a new read-only instance of ReplicaManager, bound to a specific deployed contract. +func NewReplicaManagerCaller(address common.Address, caller bind.ContractCaller) (*ReplicaManagerCaller, error) { + contract, err := bindReplicaManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ReplicaManagerCaller{contract: contract}, nil +} + +// NewReplicaManagerTransactor creates a new write-only instance of ReplicaManager, bound to a specific deployed contract. +func NewReplicaManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaManagerTransactor, error) { + contract, err := bindReplicaManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ReplicaManagerTransactor{contract: contract}, nil +} + +// NewReplicaManagerFilterer creates a new log filterer instance of ReplicaManager, bound to a specific deployed contract. +func NewReplicaManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaManagerFilterer, error) { + contract, err := bindReplicaManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ReplicaManagerFilterer{contract: contract}, nil +} + +// bindReplicaManager binds a generic wrapper to an already deployed contract. +func bindReplicaManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ReplicaManagerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaManager *ReplicaManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaManager.Contract.ReplicaManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaManager *ReplicaManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManager.Contract.ReplicaManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaManager *ReplicaManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaManager.Contract.ReplicaManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaManager *ReplicaManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaManager *ReplicaManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaManager *ReplicaManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaManager.Contract.contract.Transact(opts, method, params...) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManager *ReplicaManagerCaller) VERSION(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "VERSION") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManager *ReplicaManagerSession) VERSION() (uint8, error) { + return _ReplicaManager.Contract.VERSION(&_ReplicaManager.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManager *ReplicaManagerCallerSession) VERSION() (uint8, error) { + return _ReplicaManager.Contract.VERSION(&_ReplicaManager.CallOpts) +} + +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManager *ReplicaManagerCaller) AcceptableRoot(opts *bind.CallOpts, _remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "acceptableRoot", _remoteDomain, _optimisticSeconds, _root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManager *ReplicaManagerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + return _ReplicaManager.Contract.AcceptableRoot(&_ReplicaManager.CallOpts, _remoteDomain, _optimisticSeconds, _root) +} + +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManager *ReplicaManagerCallerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + return _ReplicaManager.Contract.AcceptableRoot(&_ReplicaManager.CallOpts, _remoteDomain, _optimisticSeconds, _root) +} + +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaConfirmedAt(opts *bind.CallOpts, _remoteDomain uint32, _root [32]byte) (*big.Int, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaConfirmedAt", _remoteDomain, _root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { + return _ReplicaManager.Contract.ActiveReplicaConfirmedAt(&_ReplicaManager.CallOpts, _remoteDomain, _root) +} + +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { + return _ReplicaManager.Contract.ActiveReplicaConfirmedAt(&_ReplicaManager.CallOpts, _remoteDomain, _root) +} + +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaMessageStatus(opts *bind.CallOpts, _remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaMessageStatus", _remoteDomain, _messageId) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + return _ReplicaManager.Contract.ActiveReplicaMessageStatus(&_ReplicaManager.CallOpts, _remoteDomain, _messageId) +} + +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + return _ReplicaManager.Contract.ActiveReplicaMessageStatus(&_ReplicaManager.CallOpts, _remoteDomain, _messageId) +} + +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManager *ReplicaManagerCaller) ActiveReplicaNonce(opts *bind.CallOpts, _remoteDomain uint32) (uint32, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "activeReplicaNonce", _remoteDomain) + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManager *ReplicaManagerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { + return _ReplicaManager.Contract.ActiveReplicaNonce(&_ReplicaManager.CallOpts, _remoteDomain) +} + +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManager *ReplicaManagerCallerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { + return _ReplicaManager.Contract.ActiveReplicaNonce(&_ReplicaManager.CallOpts, _remoteDomain) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManager *ReplicaManagerCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "allGuards") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManager *ReplicaManagerSession) AllGuards() ([]common.Address, error) { + return _ReplicaManager.Contract.AllGuards(&_ReplicaManager.CallOpts) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManager *ReplicaManagerCallerSession) AllGuards() ([]common.Address, error) { + return _ReplicaManager.Contract.AllGuards(&_ReplicaManager.CallOpts) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManager *ReplicaManagerCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "getGuard", _index) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManager *ReplicaManagerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _ReplicaManager.Contract.GetGuard(&_ReplicaManager.CallOpts, _index) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManager *ReplicaManagerCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _ReplicaManager.Contract.GetGuard(&_ReplicaManager.CallOpts, _index) +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManager *ReplicaManagerCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "guardsAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManager *ReplicaManagerSession) GuardsAmount() (*big.Int, error) { + return _ReplicaManager.Contract.GuardsAmount(&_ReplicaManager.CallOpts) +} + +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManager *ReplicaManagerCallerSession) GuardsAmount() (*big.Int, error) { + return _ReplicaManager.Contract.GuardsAmount(&_ReplicaManager.CallOpts) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManager *ReplicaManagerCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManager *ReplicaManagerSession) LocalDomain() (uint32, error) { + return _ReplicaManager.Contract.LocalDomain(&_ReplicaManager.CallOpts) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManager *ReplicaManagerCallerSession) LocalDomain() (uint32, error) { + return _ReplicaManager.Contract.LocalDomain(&_ReplicaManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManager *ReplicaManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManager *ReplicaManagerSession) Owner() (common.Address, error) { + return _ReplicaManager.Contract.Owner(&_ReplicaManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManager *ReplicaManagerCallerSession) Owner() (common.Address, error) { + return _ReplicaManager.Contract.Owner(&_ReplicaManager.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManager *ReplicaManagerCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ReplicaManager.contract.Call(opts, &out, "systemMessenger") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManager *ReplicaManagerSession) SystemMessenger() (common.Address, error) { + return _ReplicaManager.Contract.SystemMessenger(&_ReplicaManager.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManager *ReplicaManagerCallerSession) SystemMessenger() (common.Address, error) { + return _ReplicaManager.Contract.SystemMessenger(&_ReplicaManager.CallOpts) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerTransactor) Initialize(opts *bind.TransactOpts, _remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "initialize", _remoteDomain, _updater) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.Initialize(&_ReplicaManager.TransactOpts, _remoteDomain, _updater) +} + +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.Initialize(&_ReplicaManager.TransactOpts, _remoteDomain, _updater) +} + +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// +// Solidity: function process(bytes _message) returns() +func (_ReplicaManager *ReplicaManagerTransactor) Process(opts *bind.TransactOpts, _message []byte) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "process", _message) +} + +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// +// Solidity: function process(bytes _message) returns() +func (_ReplicaManager *ReplicaManagerSession) Process(_message []byte) (*types.Transaction, error) { + return _ReplicaManager.Contract.Process(&_ReplicaManager.TransactOpts, _message) +} + +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// +// Solidity: function process(bytes _message) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) Process(_message []byte) (*types.Transaction, error) { + return _ReplicaManager.Contract.Process(&_ReplicaManager.TransactOpts, _message) +} + +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManager *ReplicaManagerTransactor) Prove(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "prove", _remoteDomain, _message, _proof, _index) +} + +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManager *ReplicaManagerSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.Prove(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) +} + +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManager *ReplicaManagerTransactorSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.Prove(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) +} + +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. +// +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManager *ReplicaManagerTransactor) ProveAndProcess(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "proveAndProcess", _remoteDomain, _message, _proof, _index) +} + +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. +// +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManager *ReplicaManagerSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.ProveAndProcess(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) +} + +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. +// +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.ProveAndProcess(&_ReplicaManager.TransactOpts, _remoteDomain, _message, _proof, _index) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManager *ReplicaManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManager *ReplicaManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _ReplicaManager.Contract.RenounceOwnership(&_ReplicaManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ReplicaManager.Contract.RenounceOwnership(&_ReplicaManager.TransactOpts) +} + +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. +// +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManager *ReplicaManagerTransactor) SetConfirmation(opts *bind.TransactOpts, _remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "setConfirmation", _remoteDomain, _root, _confirmAt) +} + +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. +// +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManager *ReplicaManagerSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetConfirmation(&_ReplicaManager.TransactOpts, _remoteDomain, _root, _confirmAt) +} + +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. +// +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetConfirmation(&_ReplicaManager.TransactOpts, _remoteDomain, _root, _confirmAt) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManager *ReplicaManagerTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManager *ReplicaManagerSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetSystemMessenger(&_ReplicaManager.TransactOpts, _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetSystemMessenger(&_ReplicaManager.TransactOpts, _systemMessenger) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. +// +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerTransactor) SetUpdater(opts *bind.TransactOpts, _domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "setUpdater", _domain, _updater) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. +// +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerSession) SetUpdater(_domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetUpdater(&_ReplicaManager.TransactOpts, _domain, _updater) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. +// +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) SetUpdater(_domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.SetUpdater(&_ReplicaManager.TransactOpts, _domain, _updater) +} + +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. +// +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManager *ReplicaManagerTransactor) SubmitAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "submitAttestation", _attestation) +} + +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. +// +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManager *ReplicaManagerSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { + return _ReplicaManager.Contract.SubmitAttestation(&_ReplicaManager.TransactOpts, _attestation) +} + +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. +// +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { + return _ReplicaManager.Contract.SubmitAttestation(&_ReplicaManager.TransactOpts, _attestation) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManager *ReplicaManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManager.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManager *ReplicaManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.TransferOwnership(&_ReplicaManager.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManager *ReplicaManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManager.Contract.TransferOwnership(&_ReplicaManager.TransactOpts, newOwner) +} + +// ReplicaManagerAttestationAcceptedIterator is returned from FilterAttestationAccepted and is used to iterate over the raw logs and unpacked data for AttestationAccepted events raised by the ReplicaManager contract. +type ReplicaManagerAttestationAcceptedIterator struct { + Event *ReplicaManagerAttestationAccepted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerAttestationAcceptedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerAttestationAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerAttestationAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerAttestationAcceptedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerAttestationAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerAttestationAccepted represents a AttestationAccepted event raised by the ReplicaManager contract. +type ReplicaManagerAttestationAccepted struct { + HomeDomain uint32 + Nonce uint32 + Root [32]byte + Signature []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAttestationAccepted is a free log retrieval operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. +// +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManager *ReplicaManagerFilterer) FilterAttestationAccepted(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*ReplicaManagerAttestationAcceptedIterator, error) { + + var homeDomainRule []interface{} + for _, homeDomainItem := range homeDomain { + homeDomainRule = append(homeDomainRule, homeDomainItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var rootRule []interface{} + for _, rootItem := range root { + rootRule = append(rootRule, rootItem) + } + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "AttestationAccepted", homeDomainRule, nonceRule, rootRule) + if err != nil { + return nil, err + } + return &ReplicaManagerAttestationAcceptedIterator{contract: _ReplicaManager.contract, event: "AttestationAccepted", logs: logs, sub: sub}, nil +} + +// WatchAttestationAccepted is a free log subscription operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. +// +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManager *ReplicaManagerFilterer) WatchAttestationAccepted(opts *bind.WatchOpts, sink chan<- *ReplicaManagerAttestationAccepted, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { + + var homeDomainRule []interface{} + for _, homeDomainItem := range homeDomain { + homeDomainRule = append(homeDomainRule, homeDomainItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var rootRule []interface{} + for _, rootItem := range root { + rootRule = append(rootRule, rootItem) + } + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "AttestationAccepted", homeDomainRule, nonceRule, rootRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerAttestationAccepted) + if err := _ReplicaManager.contract.UnpackLog(event, "AttestationAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAttestationAccepted is a log parse operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. +// +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManager *ReplicaManagerFilterer) ParseAttestationAccepted(log types.Log) (*ReplicaManagerAttestationAccepted, error) { + event := new(ReplicaManagerAttestationAccepted) + if err := _ReplicaManager.contract.UnpackLog(event, "AttestationAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the ReplicaManager contract. +type ReplicaManagerGuardAddedIterator struct { + Event *ReplicaManagerGuardAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerGuardAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerGuardAdded represents a GuardAdded event raised by the ReplicaManager contract. +type ReplicaManagerGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*ReplicaManagerGuardAddedIterator, error) { + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return &ReplicaManagerGuardAddedIterator{contract: _ReplicaManager.contract, event: "GuardAdded", logs: logs, sub: sub}, nil +} + +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *ReplicaManagerGuardAdded) (event.Subscription, error) { + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerGuardAdded) + if err := _ReplicaManager.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) ParseGuardAdded(log types.Log) (*ReplicaManagerGuardAdded, error) { + event := new(ReplicaManagerGuardAdded) + if err := _ReplicaManager.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the ReplicaManager contract. +type ReplicaManagerGuardRemovedIterator struct { + Event *ReplicaManagerGuardRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerGuardRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerGuardRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerGuardRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerGuardRemoved represents a GuardRemoved event raised by the ReplicaManager contract. +type ReplicaManagerGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*ReplicaManagerGuardRemovedIterator, error) { + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return &ReplicaManagerGuardRemovedIterator{contract: _ReplicaManager.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil +} + +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *ReplicaManagerGuardRemoved) (event.Subscription, error) { + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerGuardRemoved) + if err := _ReplicaManager.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManager *ReplicaManagerFilterer) ParseGuardRemoved(log types.Log) (*ReplicaManagerGuardRemoved, error) { + event := new(ReplicaManagerGuardRemoved) + if err := _ReplicaManager.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ReplicaManager contract. +type ReplicaManagerInitializedIterator struct { + Event *ReplicaManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerInitialized represents a Initialized event raised by the ReplicaManager contract. +type ReplicaManagerInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_ReplicaManager *ReplicaManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ReplicaManagerInitializedIterator, error) { + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ReplicaManagerInitializedIterator{contract: _ReplicaManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_ReplicaManager *ReplicaManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ReplicaManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerInitialized) + if err := _ReplicaManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_ReplicaManager *ReplicaManagerFilterer) ParseInitialized(log types.Log) (*ReplicaManagerInitialized, error) { + event := new(ReplicaManagerInitialized) + if err := _ReplicaManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerNotaryAddedIterator is returned from FilterNotaryAdded and is used to iterate over the raw logs and unpacked data for NotaryAdded events raised by the ReplicaManager contract. +type ReplicaManagerNotaryAddedIterator struct { + Event *ReplicaManagerNotaryAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerNotaryAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerNotaryAdded represents a NotaryAdded event raised by the ReplicaManager contract. +type ReplicaManagerNotaryAdded struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNotaryAdded is a free log retrieval operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) FilterNotaryAdded(opts *bind.FilterOpts, domain []uint32) (*ReplicaManagerNotaryAddedIterator, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "NotaryAdded", domainRule) + if err != nil { + return nil, err + } + return &ReplicaManagerNotaryAddedIterator{contract: _ReplicaManager.contract, event: "NotaryAdded", logs: logs, sub: sub}, nil +} + +// WatchNotaryAdded is a free log subscription operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) WatchNotaryAdded(opts *bind.WatchOpts, sink chan<- *ReplicaManagerNotaryAdded, domain []uint32) (event.Subscription, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "NotaryAdded", domainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerNotaryAdded) + if err := _ReplicaManager.contract.UnpackLog(event, "NotaryAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNotaryAdded is a log parse operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. +// +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) ParseNotaryAdded(log types.Log) (*ReplicaManagerNotaryAdded, error) { + event := new(ReplicaManagerNotaryAdded) + if err := _ReplicaManager.contract.UnpackLog(event, "NotaryAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerNotaryRemovedIterator is returned from FilterNotaryRemoved and is used to iterate over the raw logs and unpacked data for NotaryRemoved events raised by the ReplicaManager contract. +type ReplicaManagerNotaryRemovedIterator struct { + Event *ReplicaManagerNotaryRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerNotaryRemovedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerNotaryRemoved represents a NotaryRemoved event raised by the ReplicaManager contract. +type ReplicaManagerNotaryRemoved struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNotaryRemoved is a free log retrieval operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) FilterNotaryRemoved(opts *bind.FilterOpts, domain []uint32) (*ReplicaManagerNotaryRemovedIterator, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "NotaryRemoved", domainRule) + if err != nil { + return nil, err + } + return &ReplicaManagerNotaryRemovedIterator{contract: _ReplicaManager.contract, event: "NotaryRemoved", logs: logs, sub: sub}, nil +} + +// WatchNotaryRemoved is a free log subscription operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) WatchNotaryRemoved(opts *bind.WatchOpts, sink chan<- *ReplicaManagerNotaryRemoved, domain []uint32) (event.Subscription, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "NotaryRemoved", domainRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerNotaryRemoved) + if err := _ReplicaManager.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNotaryRemoved is a log parse operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. +// +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManager *ReplicaManagerFilterer) ParseNotaryRemoved(log types.Log) (*ReplicaManagerNotaryRemoved, error) { + event := new(ReplicaManagerNotaryRemoved) + if err := _ReplicaManager.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ReplicaManager contract. +type ReplicaManagerOwnershipTransferredIterator struct { + Event *ReplicaManagerOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerOwnershipTransferred represents a OwnershipTransferred event raised by the ReplicaManager contract. +type ReplicaManagerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ReplicaManager *ReplicaManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ReplicaManagerOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ReplicaManagerOwnershipTransferredIterator{contract: _ReplicaManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ReplicaManager *ReplicaManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ReplicaManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { var previousOwnerRule []interface{} for _, previousOwnerItem := range previousOwner { @@ -4299,7 +6279,162 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchProcess(opts *bind.WatchOpts messageHashRule = append(messageHashRule, messageHashItem) } - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Process", remoteDomainRule, messageHashRule) + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Process", remoteDomainRule, messageHashRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerProcess) + if err := _ReplicaManager.contract.UnpackLog(event, "Process", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseProcess is a log parse operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// +// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) +func (_ReplicaManager *ReplicaManagerFilterer) ParseProcess(log types.Log) (*ReplicaManagerProcess, error) { + event := new(ReplicaManagerProcess) + if err := _ReplicaManager.contract.UnpackLog(event, "Process", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ReplicaManagerSetConfirmationIterator is returned from FilterSetConfirmation and is used to iterate over the raw logs and unpacked data for SetConfirmation events raised by the ReplicaManager contract. +type ReplicaManagerSetConfirmationIterator struct { + Event *ReplicaManagerSetConfirmation // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerSetConfirmationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerSetConfirmation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerSetConfirmation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerSetConfirmationIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerSetConfirmationIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ReplicaManagerSetConfirmation represents a SetConfirmation event raised by the ReplicaManager contract. +type ReplicaManagerSetConfirmation struct { + RemoteDomain uint32 + Root [32]byte + PreviousConfirmAt *big.Int + NewConfirmAt *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetConfirmation is a free log retrieval operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManager *ReplicaManagerFilterer) FilterSetConfirmation(opts *bind.FilterOpts, remoteDomain []uint32, root [][32]byte) (*ReplicaManagerSetConfirmationIterator, error) { + + var remoteDomainRule []interface{} + for _, remoteDomainItem := range remoteDomain { + remoteDomainRule = append(remoteDomainRule, remoteDomainItem) + } + var rootRule []interface{} + for _, rootItem := range root { + rootRule = append(rootRule, rootItem) + } + + logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) + if err != nil { + return nil, err + } + return &ReplicaManagerSetConfirmationIterator{contract: _ReplicaManager.contract, event: "SetConfirmation", logs: logs, sub: sub}, nil +} + +// WatchSetConfirmation is a free log subscription operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManager *ReplicaManagerFilterer) WatchSetConfirmation(opts *bind.WatchOpts, sink chan<- *ReplicaManagerSetConfirmation, remoteDomain []uint32, root [][32]byte) (event.Subscription, error) { + + var remoteDomainRule []interface{} + for _, remoteDomainItem := range remoteDomain { + remoteDomainRule = append(remoteDomainRule, remoteDomainItem) + } + var rootRule []interface{} + for _, rootItem := range root { + rootRule = append(rootRule, rootItem) + } + + logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) if err != nil { return nil, err } @@ -4309,8 +6444,8 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchProcess(opts *bind.WatchOpts select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerProcess) - if err := _ReplicaManager.contract.UnpackLog(event, "Process", log); err != nil { + event := new(ReplicaManagerSetConfirmation) + if err := _ReplicaManager.contract.UnpackLog(event, "SetConfirmation", log); err != nil { return err } event.Raw = log @@ -4331,1097 +6466,1328 @@ func (_ReplicaManager *ReplicaManagerFilterer) WatchProcess(opts *bind.WatchOpts }), nil } -// ParseProcess is a log parse operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// ParseSetConfirmation is a log parse operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. // -// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) -func (_ReplicaManager *ReplicaManagerFilterer) ParseProcess(log types.Log) (*ReplicaManagerProcess, error) { - event := new(ReplicaManagerProcess) - if err := _ReplicaManager.contract.UnpackLog(event, "Process", log); err != nil { +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManager *ReplicaManagerFilterer) ParseSetConfirmation(log types.Log) (*ReplicaManagerSetConfirmation, error) { + event := new(ReplicaManagerSetConfirmation) + if err := _ReplicaManager.contract.UnpackLog(event, "SetConfirmation", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerSetConfirmationIterator is returned from FilterSetConfirmation and is used to iterate over the raw logs and unpacked data for SetConfirmation events raised by the ReplicaManager contract. -type ReplicaManagerSetConfirmationIterator struct { - Event *ReplicaManagerSetConfirmation // Event containing the contract specifics and raw log +// ReplicaManagerHarnessMetaData contains all meta data concerning the ReplicaManagerHarness contract. +var ReplicaManagerHarnessMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"AttestationAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"updaterTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"relayerTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"proverTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"processorTip\",\"type\":\"uint96\"}],\"name\":\"LogTips\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"addNotary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"isNotary\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sensitiveValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_status\",\"type\":\"bytes32\"}],\"name\":\"setMessageStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newValue\",\"type\":\"uint256\"}],\"name\":\"setSensitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "ffa1ad74": "VERSION()", + "15a046aa": "acceptableRoot(uint32,uint32,bytes32)", + "7dfdba28": "activeReplicaConfirmedAt(uint32,bytes32)", + "63415514": "activeReplicaMessageStatus(uint32,bytes32)", + "b65672d3": "activeReplicaNonce(uint32)", + "2af678b0": "addNotary(uint32,address)", + "9fe03fa2": "allGuards()", + "629ddf69": "getGuard(uint256)", + "246c2449": "guardsAmount()", + "8624c35c": "initialize(uint32,address)", + "e98fae1f": "isNotary(uint32,address)", + "8d3638f4": "localDomain()", + "8da5cb5b": "owner()", + "928bc4b2": "process(bytes)", + "4f63be3f": "prove(uint32,bytes,bytes32[32],uint256)", + "68705275": "proveAndProcess(uint32,bytes,bytes32[32],uint256)", + "715018a6": "renounceOwnership()", + "089d2894": "sensitiveValue()", + "9df7d36d": "setConfirmation(uint32,bytes32,uint256)", + "bfd84d36": "setMessageStatus(uint32,bytes32,bytes32)", + "48639d24": "setSensitiveValue(uint256)", + "b7bc563e": "setSystemMessenger(address)", + "61bc3111": "setUpdater(uint32,address)", + "f646a512": "submitAttestation(bytes)", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + }, + Bin: "0x60a06040523480156200001157600080fd5b506040516200320338038062003203833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b6080516131676200009c60003960008181610335015281816109bd015261103e01526131676000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80638d3638f4116100ee578063b7bc563e11610097578063e98fae1f11610071578063e98fae1f14610441578063f2fde38b14610454578063f646a51214610467578063ffa1ad741461047a57600080fd5b8063b7bc563e146103fb578063bfd84d361461040e578063ccbdf9c91461042157600080fd5b80639df7d36d116100c85780639df7d36d1461039d5780639fe03fa2146103b0578063b65672d3146103c557600080fd5b80638d3638f4146103305780638da5cb5b1461036c578063928bc4b21461038a57600080fd5b806361bc31111161015b578063687052751161013557806368705275146102c1578063715018a6146102d45780637dfdba28146102dc5780638624c35c1461031d57600080fd5b806361bc311114610235578063629ddf6914610248578063634155141461028057600080fd5b80632af678b01161018c5780632af678b0146101fa57806348639d241461020f5780634f63be3f1461022257600080fd5b8063089d2894146101b357806315a046aa146101cf578063246c2449146101f2575b600080fd5b6101bc60fd5481565b6040519081526020015b60405180910390f35b6101e26101dd366004612ad5565b610494565b60405190151581526020016101c6565b6101bc6104f1565b61020d610208366004612b33565b610502565b005b61020d61021d366004612b6a565b610511565b6101e2610230366004612c5d565b61051e565b61020d610243366004612b33565b610698565b61025b610256366004612b6a565b6106ff565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b6101bc61028e366004612ccd565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b61020d6102cf366004612c5d565b610712565b61020d610779565b6101bc6102ea366004612ccd565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b61020d61032b366004612b33565b6107e2565b6103577f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101c6565b60335473ffffffffffffffffffffffffffffffffffffffff1661025b565b61020d610398366004612cf7565b610964565b61020d6103ab366004612d2c565b610d02565b6103b8610df6565b6040516101c69190612d5f565b6103576103d3366004612db9565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b61020d610409366004612dd4565b610e02565b61020d61041c366004612d2c565b610eb0565b60655461025b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101e261044f366004612b33565b610ee1565b61020d610462366004612dd4565b610f1f565b61020d610475366004612cf7565b61101b565b610482600081565b60405160ff90911681526020016101c6565b63ffffffff8316600090815260ce6020908152604080832054835260cd82528083208484526001019091528120548082036104d35760009150506104ea565b6104e363ffffffff851682612e20565b4210159150505b9392505050565b60006104fd60986111f6565b905090565b61050c8282611200565b505050565b6105196112fd565b60fd55565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff16600281111561056d5761056d612e38565b146105bf5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561061d5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016105b6565b60006106538387602080602002604051908101604052809291908260208002808284376000920191909152508991506113649050565b600081815260018401602052604090205490915015610688576000928352600291909101602052604090912055506001610690565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146105025760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b600061070c60988361141e565b92915050565b61071e8484848461051e565b61076a5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016105b6565b61077383610964565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107e05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b565b60006107ee600161142a565b9050801561082357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61082b611581565b6108358383611200565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556108e78360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561050c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b600061096f82611606565b9050600061098262ffffff198316611614565b9050600061099562ffffff198316611654565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f0000000000000000000000000000000000000000000000000000000000000000166109ec62ffffff19851661167e565b63ffffffff1614610a3f5760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016105b6565b6000610a5062ffffff19861661169f565b6000818152600284016020526040902054909150610a6d816116fc565b610ab95760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016105b6565b610ad284610acc62ffffff198816611710565b83610494565b610b1e5760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016105b6565b60cb5460ff16600114610b735760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016105b6565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610bb2610bad62ffffff198816611731565b611768565b6000828152600284016020526040812060019055610bdd610bd862ffffff198816611800565b611821565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610c0b62ffffff198a16611863565b610c1a62ffffff198b16611884565b600087815260018a016020526040902054610c48610c3d62ffffff198f166118a5565b62ffffff19166118e4565b6040518663ffffffff1660e01b8152600401610c68959493929190612ed2565b600060405180830381600087803b158015610c8257600080fd5b505af1158015610c96573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610dac9083908690869061193716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60606104fd609861194b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b63ffffffff808416600090815260ce6020908152604080832054835260cd909152902061050c918490849061140a16565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415156104ea565b60335473ffffffffffffffffffffffffffffffffffffffff163314610f865760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b73ffffffffffffffffffffffffffffffffffffffff811661100f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105b6565b61101881611958565b50565b6000611026826119cf565b915050600061103a8262ffffff1916611b09565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16036110b75760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016105b6565b60006110c862ffffff198416611b1d565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116111435760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016105b6565b600061115462ffffff198616611b31565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6111d9610c3d8a62ffffff1916611b46565b6040516111e69190612f12565b60405180910390a4505050505050565b600061070c825490565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156112445750600061070c565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146107e05760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e6765720000000000000000000000000000000060448201526064016105b6565b8260005b602081101561140257600183821c16600085836020811061138b5761138b612f25565b60200201519050816001036113cb5760408051602081018390529081018590526060016040516020818303038152906040528051906020012093506113f8565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611368565b509392505050565b600091825260029092016020526040902055565b60006104ea8383611b79565b60008054610100900460ff16156114c7578160ff16600114801561144d5750303b155b6114bf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105b6565b506000919050565b60005460ff8084169116106115445760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105b6565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166115fe5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105b6565b6107e0611ba3565b600061070c82610539611c29565b60008161162962ffffff198216610539611c4d565b5061164b83611639856001611d4e565b611644866002611d4e565b6001611d80565b91505b50919050565b60008161166a60015b62ffffff19831690611c4d565b5061164b62ffffff19841660026004611d9f565b60008161168b600161165d565b5061164b62ffffff198416602a6004611d9f565b6000806116ba8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006116e48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b6000811580159061070c5750506001141590565b60008161171d600161165d565b5061164b62ffffff198416604e6004611d9f565b60008161174662ffffff198216610539611c4d565b5061164b83611756856002611d4e565b611761866003611d4e565b6002611d80565b7f1dad5ea7bf29006ead0af41296d42c169129acd1ec64b3639ebe94b8c01bfa1161179862ffffff198316611dcf565b6117a762ffffff198416611dfd565b6117b662ffffff198516611e1e565b6117c562ffffff198616611e3f565b604080516bffffffffffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190a150565b60008161180d600161165d565b5061164b62ffffff198416602e6020611e60565b600074010000000000000000000000000000000000000000820161185d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b8161070c565b600081611870600161165d565b5061164b62ffffff19841660266004611d9f565b600081611891600161165d565b5061164b62ffffff19841660066020611e60565b6000816118ba62ffffff198216610539611c4d565b5061164b836118ca856003611d4e565b601886901c6bffffffffffffffffffffffff166003611d80565b60606000806119018460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506040519150819250611926848360200161201e565b508181016020016040529052919050565b600091825260019092016020526040902055565b606060006104ea836121c3565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806119dc8382611c29565b905060286bffffffffffffffffffffffff601883901c1611611a405760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016105b6565b611a69611a5262ffffff19831661221f565b611a64610c3d62ffffff198516611b46565b612234565b9150611ab8611a7d62ffffff198316611b09565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b611b045760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f746172790000000000000000000060448201526064016105b6565b915091565b600061070c62ffffff198316826004611d9f565b600061070c62ffffff198316600480611d9f565b600061070c62ffffff19831660086020611e60565b600061070c6028611b6981601886901c6bffffffffffffffffffffffff16612f54565b62ffffff198516919060006122ab565b6000826000018281548110611b9057611b90612f25565b9060005260206000200154905092915050565b600054610100900460ff16611c205760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105b6565b6107e033611958565b815160009060208401611c4464ffffffffff85168284612321565b95945050505050565b6000611c598383612368565b611d47576000611c78611c6c8560d81c90565b64ffffffffff1661238b565b9150506000611c8d8464ffffffffff1661238b565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016105b69190612f12565b5090919050565b60006104ea6002836004811115611d6757611d67612e38565b611d719190612f6b565b62ffffff198516906002611d9f565b6000611c4484611d908186612f54565b62ffffff1988169190856122ab565b6000611dac826020612fa8565b611db7906008612fcb565b60ff16611dc5858585611e60565b901c949350505050565b600081611ddc600261165d565b50611df062ffffff1984166002600c611d9f565b63ffffffff169392505050565b600081611e0a600261165d565b50611df062ffffff198416600e600c611d9f565b600081611e2b600261165d565b50611df062ffffff198416601a600c611d9f565b600081611e4c600261165d565b50611df062ffffff1984166026600c611d9f565b60008160ff16600003611e75575060006104ea565b611e8d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611ea860ff841685612e20565b1115611f2057611f07611ec98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611eef8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16612475565b60405162461bcd60e51b81526004016105b69190612f12565b60208260ff161115611f9a5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016105b6565b600882026000611fb88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff198084160361209b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016105b6565b6120a4836124e3565b6121165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016105b6565b60006121308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061215a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561217f5760206060fd5b8285848460045afa506121b96121958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561221357602002820191906000526020600020905b8154815260200190600101908083116121ff575b50505050509050919050565b600061070c62ffffff198316826028816122ab565b60008061224662ffffff19851661169f565b905061229f816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506106908184612520565b6000806122c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506122df8661253c565b846122ea8784612e20565b6122f49190612e20565b11156123075762ffffff19915050610690565b6123118582612e20565b90506121b98364ffffffffff1682865b60008061232e8385612e20565b905060405181111561233e575060005b806000036123535762ffffff199150506104ea565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff1661237c8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156123fe5760006123aa826008612fcb565b60ff1685901c90506123bb81612584565b61ffff16841793508160ff166010146123d657601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612391565b50600f5b60ff8160ff16101561246f57600061241b826008612fcb565b60ff1685901c905061242c81612584565b61ffff16831792508160ff1660001461244757601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612402565b50915091565b606060006124828661238b565b91505060006124908661238b565b915050600061249e8661238b565b91505060006124ac8661238b565b915050838383836040516020016124c69493929190612ff4565b604051602081830303815290604052945050505050949350505050565b60006124ef8260d81c90565b64ffffffffff1664ffffffffff0361250957506000919050565b60006125148361253c565b60405110199392505050565b600080600061252f85856125b6565b9150915061140281612624565b60006125568260181c6bffffffffffffffffffffffff1690565b61256e8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061259660048360ff16901c612810565b60ff1661ffff919091161760081b6125ad82612810565b60ff1617919050565b60008082516041036125ec5760208301516040840151606085015160001a6125e087828585612957565b9450945050505061261d565b8251604003612615576020830151604084015161260a868383612a6f565b93509350505061261d565b506000905060025b9250929050565b600081600481111561263857612638612e38565b036126405750565b600181600481111561265457612654612e38565b036126a15760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105b6565b60028160048111156126b5576126b5612e38565b036127025760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105b6565b600381600481111561271657612716612e38565b036127895760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105b6565b600481600481111561279d5761279d612e38565b036110185760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105b6565b600060f08083179060ff8216900361282b5750603092915050565b8060ff1660f10361283f5750603192915050565b8060ff1660f2036128535750603292915050565b8060ff1660f3036128675750603392915050565b8060ff1660f40361287b5750603492915050565b8060ff1660f50361288f5750603592915050565b8060ff1660f6036128a35750603692915050565b8060ff1660f7036128b75750603792915050565b8060ff1660f8036128cb5750603892915050565b8060ff1660f9036128df5750603992915050565b8060ff1660fa036128f35750606192915050565b8060ff1660fb036129075750606292915050565b8060ff1660fc0361291b5750606392915050565b8060ff1660fd0361292f5750606492915050565b8060ff1660fe036129435750606592915050565b8060ff1660ff0361164e5750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561298e5750600090506003612a66565b8460ff16601b141580156129a657508460ff16601c14155b156129b75750600090506004612a66565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612a0b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a5f57600060019250925050612a66565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612aa560ff86901c601b612e20565b9050612ab387828885612957565b935093505050935093915050565b803563ffffffff8116811461157c57600080fd5b600080600060608486031215612aea57600080fd5b612af384612ac1565b9250612b0160208501612ac1565b9150604084013590509250925092565b73ffffffffffffffffffffffffffffffffffffffff8116811461101857600080fd5b60008060408385031215612b4657600080fd5b612b4f83612ac1565b91506020830135612b5f81612b11565b809150509250929050565b600060208284031215612b7c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612bc357600080fd5b813567ffffffffffffffff80821115612bde57612bde612b83565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612c2457612c24612b83565b81604052838152866020858801011115612c3d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806104608587031215612c7457600080fd5b612c7d85612ac1565b9350602085013567ffffffffffffffff811115612c9957600080fd5b612ca587828801612bb2565b935050610440850186811115612cba57600080fd5b9396929550505060409290920191903590565b60008060408385031215612ce057600080fd5b612ce983612ac1565b946020939093013593505050565b600060208284031215612d0957600080fd5b813567ffffffffffffffff811115612d2057600080fd5b61069084828501612bb2565b600080600060608486031215612d4157600080fd5b612d4a84612ac1565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612dad57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d7b565b50909695505050505050565b600060208284031215612dcb57600080fd5b6104ea82612ac1565b600060208284031215612de657600080fd5b81356104ea81612b11565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612e3357612e33612df1565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612e8d57602081850181015186830182015201612e71565b81811115612e9f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612f0760a0830184612e67565b979650505050505050565b6020815260006104ea6020830184612e67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612f6657612f66612df1565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612fa357612fa3612df1565b500290565b600060ff821660ff841680821015612fc257612fc2612df1565b90039392505050565b600060ff821660ff84168160ff0481118215151615612fec57612fec612df1565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016121b956fea264697066735822122077912efc3717025575bd9990ab6b1c994564411fcd37e67822c74bd01e33dc7664736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// ReplicaManagerHarnessABI is the input ABI used to generate the binding from. +// Deprecated: Use ReplicaManagerHarnessMetaData.ABI instead. +var ReplicaManagerHarnessABI = ReplicaManagerHarnessMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Deprecated: Use ReplicaManagerHarnessMetaData.Sigs instead. +// ReplicaManagerHarnessFuncSigs maps the 4-byte function signature to its string representation. +var ReplicaManagerHarnessFuncSigs = ReplicaManagerHarnessMetaData.Sigs + +// ReplicaManagerHarnessBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ReplicaManagerHarnessMetaData.Bin instead. +var ReplicaManagerHarnessBin = ReplicaManagerHarnessMetaData.Bin + +// DeployReplicaManagerHarness deploys a new Ethereum contract, binding an instance of ReplicaManagerHarness to it. +func DeployReplicaManagerHarness(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *ReplicaManagerHarness, error) { + parsed, err := ReplicaManagerHarnessMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaManagerHarnessBin), backend, _localDomain) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ReplicaManagerHarness{ReplicaManagerHarnessCaller: ReplicaManagerHarnessCaller{contract: contract}, ReplicaManagerHarnessTransactor: ReplicaManagerHarnessTransactor{contract: contract}, ReplicaManagerHarnessFilterer: ReplicaManagerHarnessFilterer{contract: contract}}, nil } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerSetConfirmationIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// ReplicaManagerHarness is an auto generated Go binding around an Ethereum contract. +type ReplicaManagerHarness struct { + ReplicaManagerHarnessCaller // Read-only binding to the contract + ReplicaManagerHarnessTransactor // Write-only binding to the contract + ReplicaManagerHarnessFilterer // Log filterer for contract events +} + +// ReplicaManagerHarnessCaller is an auto generated read-only Go binding around an Ethereum contract. +type ReplicaManagerHarnessCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerHarnessTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ReplicaManagerHarnessTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerHarnessFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ReplicaManagerHarnessFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ReplicaManagerHarnessSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ReplicaManagerHarnessSession struct { + Contract *ReplicaManagerHarness // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaManagerHarnessCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ReplicaManagerHarnessCallerSession struct { + Contract *ReplicaManagerHarnessCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ReplicaManagerHarnessTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ReplicaManagerHarnessTransactorSession struct { + Contract *ReplicaManagerHarnessTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ReplicaManagerHarnessRaw is an auto generated low-level Go binding around an Ethereum contract. +type ReplicaManagerHarnessRaw struct { + Contract *ReplicaManagerHarness // Generic contract binding to access the raw methods on +} + +// ReplicaManagerHarnessCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ReplicaManagerHarnessCallerRaw struct { + Contract *ReplicaManagerHarnessCaller // Generic read-only contract binding to access the raw methods on +} + +// ReplicaManagerHarnessTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ReplicaManagerHarnessTransactorRaw struct { + Contract *ReplicaManagerHarnessTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewReplicaManagerHarness creates a new instance of ReplicaManagerHarness, bound to a specific deployed contract. +func NewReplicaManagerHarness(address common.Address, backend bind.ContractBackend) (*ReplicaManagerHarness, error) { + contract, err := bindReplicaManagerHarness(address, backend, backend, backend) + if err != nil { + return nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerSetConfirmation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + return &ReplicaManagerHarness{ReplicaManagerHarnessCaller: ReplicaManagerHarnessCaller{contract: contract}, ReplicaManagerHarnessTransactor: ReplicaManagerHarnessTransactor{contract: contract}, ReplicaManagerHarnessFilterer: ReplicaManagerHarnessFilterer{contract: contract}}, nil +} - default: - return false - } +// NewReplicaManagerHarnessCaller creates a new read-only instance of ReplicaManagerHarness, bound to a specific deployed contract. +func NewReplicaManagerHarnessCaller(address common.Address, caller bind.ContractCaller) (*ReplicaManagerHarnessCaller, error) { + contract, err := bindReplicaManagerHarness(address, caller, nil, nil) + if err != nil { + return nil, err } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerSetConfirmation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + return &ReplicaManagerHarnessCaller{contract: contract}, nil +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() +// NewReplicaManagerHarnessTransactor creates a new write-only instance of ReplicaManagerHarness, bound to a specific deployed contract. +func NewReplicaManagerHarnessTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaManagerHarnessTransactor, error) { + contract, err := bindReplicaManagerHarness(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ReplicaManagerHarnessTransactor{contract: contract}, nil +} + +// NewReplicaManagerHarnessFilterer creates a new log filterer instance of ReplicaManagerHarness, bound to a specific deployed contract. +func NewReplicaManagerHarnessFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaManagerHarnessFilterer, error) { + contract, err := bindReplicaManagerHarness(address, nil, nil, filterer) + if err != nil { + return nil, err } + return &ReplicaManagerHarnessFilterer{contract: contract}, nil } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerSetConfirmationIterator) Error() error { - return it.fail +// bindReplicaManagerHarness binds a generic wrapper to an already deployed contract. +func bindReplicaManagerHarness(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ReplicaManagerHarnessABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ReplicaManagerSetConfirmationIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaManagerHarness *ReplicaManagerHarnessRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaManagerHarness.Contract.ReplicaManagerHarnessCaller.contract.Call(opts, result, method, params...) } -// ReplicaManagerSetConfirmation represents a SetConfirmation event raised by the ReplicaManager contract. -type ReplicaManagerSetConfirmation struct { - RemoteDomain uint32 - Root [32]byte - PreviousConfirmAt *big.Int - NewConfirmAt *big.Int - Raw types.Log // Blockchain specific contextual infos +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaManagerHarness *ReplicaManagerHarnessRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.ReplicaManagerHarnessTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaManagerHarness *ReplicaManagerHarnessRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.ReplicaManagerHarnessTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ReplicaManagerHarness.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.contract.Transact(opts, method, params...) } -// FilterSetConfirmation is a free log retrieval operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. // -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManager *ReplicaManagerFilterer) FilterSetConfirmation(opts *bind.FilterOpts, remoteDomain []uint32, root [][32]byte) (*ReplicaManagerSetConfirmationIterator, error) { - - var remoteDomainRule []interface{} - for _, remoteDomainItem := range remoteDomain { - remoteDomainRule = append(remoteDomainRule, remoteDomainItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) VERSION(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "VERSION") - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) if err != nil { - return nil, err + return *new(uint8), err } - return &ReplicaManagerSetConfirmationIterator{contract: _ReplicaManager.contract, event: "SetConfirmation", logs: logs, sub: sub}, nil + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + } -// WatchSetConfirmation is a free log subscription operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. // -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManager *ReplicaManagerFilterer) WatchSetConfirmation(opts *bind.WatchOpts, sink chan<- *ReplicaManagerSetConfirmation, remoteDomain []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) VERSION() (uint8, error) { + return _ReplicaManagerHarness.Contract.VERSION(&_ReplicaManagerHarness.CallOpts) +} - var remoteDomainRule []interface{} - for _, remoteDomainItem := range remoteDomain { - remoteDomainRule = append(remoteDomainRule, remoteDomainItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) VERSION() (uint8, error) { + return _ReplicaManagerHarness.Contract.VERSION(&_ReplicaManagerHarness.CallOpts) +} + +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) AcceptableRoot(opts *bind.CallOpts, _remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "acceptableRoot", _remoteDomain, _optimisticSeconds, _root) - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) if err != nil { - return nil, err + return *new(bool), err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerSetConfirmation) - if err := _ReplicaManager.contract.UnpackLog(event, "SetConfirmation", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + } -// ParseSetConfirmation is a log parse operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. // -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManager *ReplicaManagerFilterer) ParseSetConfirmation(log types.Log) (*ReplicaManagerSetConfirmation, error) { - event := new(ReplicaManagerSetConfirmation) - if err := _ReplicaManager.contract.UnpackLog(event, "SetConfirmation", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + return _ReplicaManagerHarness.Contract.AcceptableRoot(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _optimisticSeconds, _root) } -// ReplicaManagerUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the ReplicaManager contract. -type ReplicaManagerUpdateIterator struct { - Event *ReplicaManagerUpdate // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// +// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { + return _ReplicaManagerHarness.Contract.AcceptableRoot(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _optimisticSeconds, _root) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerUpdateIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) ActiveReplicaConfirmedAt(opts *bind.CallOpts, _remoteDomain uint32, _root [32]byte) (*big.Int, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "activeReplicaConfirmedAt", _remoteDomain, _root) - default: - return false - } + if err != nil { + return *new(*big.Int), err } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(ReplicaManagerUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) -// Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerUpdateIterator) Error() error { - return it.fail -} + return out0, err -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *ReplicaManagerUpdateIterator) Close() error { - it.sub.Unsubscribe() - return nil } -// ReplicaManagerUpdate represents a Update event raised by the ReplicaManager contract. -type ReplicaManagerUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { + return _ReplicaManagerHarness.Contract.ActiveReplicaConfirmedAt(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _root) } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManager *ReplicaManagerFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*ReplicaManagerUpdateIterator, error) { +// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { + return _ReplicaManagerHarness.Contract.ActiveReplicaConfirmedAt(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _root) +} - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) ActiveReplicaMessageStatus(opts *bind.CallOpts, _remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "activeReplicaMessageStatus", _remoteDomain, _messageId) - logs, sub, err := _ReplicaManager.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new([32]byte), err } - return &ReplicaManagerUpdateIterator{contract: _ReplicaManager.contract, event: "Update", logs: logs, sub: sub}, nil -} -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. -// -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManager *ReplicaManagerFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *ReplicaManagerUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } + return out0, err - logs, sub, err := _ReplicaManager.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerUpdate) - if err := _ReplicaManager.contract.UnpackLog(event, "Update", log); err != nil { - return err - } - event.Raw = log +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + return _ReplicaManagerHarness.Contract.ActiveReplicaMessageStatus(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _messageId) +} + +// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// +// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { + return _ReplicaManagerHarness.Contract.ActiveReplicaMessageStatus(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _messageId) } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManager *ReplicaManagerFilterer) ParseUpdate(log types.Log) (*ReplicaManagerUpdate, error) { - event := new(ReplicaManagerUpdate) - if err := _ReplicaManager.contract.UnpackLog(event, "Update", log); err != nil { - return nil, err +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) ActiveReplicaNonce(opts *bind.CallOpts, _remoteDomain uint32) (uint32, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "activeReplicaNonce", _remoteDomain) + + if err != nil { + return *new(uint32), err } - event.Raw = log - return event, nil -} -// ReplicaManagerHarnessMetaData contains all meta data concerning the ReplicaManagerHarness contract. -var ReplicaManagerHarnessMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"updaterTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"relayerTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"proverTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"processorTip\",\"type\":\"uint96\"}],\"name\":\"LogTips\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sensitiveValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_status\",\"type\":\"bytes32\"}],\"name\":\"setMessageStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newValue\",\"type\":\"uint256\"}],\"name\":\"setSensitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "ffa1ad74": "VERSION()", - "15a046aa": "acceptableRoot(uint32,uint32,bytes32)", - "7dfdba28": "activeReplicaConfirmedAt(uint32,bytes32)", - "63415514": "activeReplicaMessageStatus(uint32,bytes32)", - "b65672d3": "activeReplicaNonce(uint32)", - "8624c35c": "initialize(uint32,address)", - "8d3638f4": "localDomain()", - "8da5cb5b": "owner()", - "928bc4b2": "process(bytes)", - "4f63be3f": "prove(uint32,bytes,bytes32[32],uint256)", - "68705275": "proveAndProcess(uint32,bytes,bytes32[32],uint256)", - "715018a6": "renounceOwnership()", - "089d2894": "sensitiveValue()", - "9df7d36d": "setConfirmation(uint32,bytes32,uint256)", - "bfd84d36": "setMessageStatus(uint32,bytes32,bytes32)", - "48639d24": "setSensitiveValue(uint256)", - "b7bc563e": "setSystemMessenger(address)", - "9d54f419": "setUpdater(address)", - "f646a512": "submitAttestation(bytes)", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "df034cd0": "updater()", - }, - Bin: "0x60a06040523480156200001157600080fd5b506040516200301c3803806200301c833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612f806200009c600039600081816102a3015281816108b40152610f5b0152612f806000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063928bc4b2116100d8578063bfd84d361161008c578063f2fde38b11610066578063f2fde38b146103ee578063f646a51214610401578063ffa1ad741461041457600080fd5b8063bfd84d361461039b578063ccbdf9c9146103ae578063df034cd0146103ce57600080fd5b80639df7d36d116100bd5780639df7d36d1461033f578063b65672d314610352578063b7bc563e1461038857600080fd5b8063928bc4b2146103195780639d54f4191461032c57600080fd5b8063687052751161013a5780638624c35c116101145780638624c35c1461028b5780638d3638f41461029e5780638da5cb5b146102da57600080fd5b8063687052751461022f578063715018a6146102425780637dfdba281461024a57600080fd5b806348639d241161016b57806348639d24146101c65780634f63be3f146101db57806363415514146101ee57600080fd5b8063089d28941461018757806315a046aa146101a3575b600080fd5b61019060fb5481565b6040519081526020015b60405180910390f35b6101b66101b1366004612948565b61042e565b604051901515815260200161019a565b6101d96101d4366004612984565b61048b565b005b6101b66101e9366004612a77565b610498565b6101906101fc366004612ae7565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b6101d961023d366004612a77565b610612565b6101d9610679565b610190610258366004612ae7565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101d9610299366004612b33565b6106e2565b6102c57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019a565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019a565b6101d9610327366004612b6a565b61085b565b6101d961033a366004612b9f565b610bf9565b6101d961034d366004612bbc565b610c6c565b6102c5610360366004612bef565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101d9610396366004612b9f565b610d60565b6101d96103a9366004612bbc565b610e0e565b6066546102f49073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102f49073ffffffffffffffffffffffffffffffffffffffff1681565b6101d96103fc366004612b9f565b610e3f565b6101d961040f366004612b6a565b610f38565b61041c600081565b60405160ff909116815260200161019a565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361046d576000915050610484565b61047d63ffffffff851682612c39565b4210159150505b9392505050565b610493611113565b60fb55565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff1660028111156104e7576104e7612c51565b146105395760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105975760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e65000000000000000000000000006044820152606401610530565b60006105cd83876020806020026040519081016040528092919082602080028082843760009201919091525089915061117a9050565b60008181526001840160205260409020549091501561060257600092835260029190910160205260409091205550600161060a565b600093505050505b949350505050565b61061e84848484610498565b61066a5760405162461bcd60e51b815260206004820152600660248201527f2170726f766500000000000000000000000000000000000000000000000000006044820152606401610530565b6106738361085b565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106e05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b565b60006106ee6001611234565b9050801561072357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61072c8261138b565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107dd8360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc6020526040902055801561085657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061086682611410565b9050600061087962ffffff198316611424565b9050600061088c62ffffff198316611464565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f0000000000000000000000000000000000000000000000000000000000000000166108e362ffffff19851661148e565b63ffffffff16146109365760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e00000000000000000000000000000000000000006044820152606401610530565b600061094762ffffff1986166114af565b60008181526002840160205260409020549091506109648161150c565b6109b05760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f6365737365640000000000000000000000006044820152606401610530565b6109c9846109c362ffffff198816611520565b8361042e565b610a155760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e647300000000000000000000000000006044820152606401610530565b60c95460ff16600114610a6a5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e74000000000000000000000000000000000000000000006044820152606401610530565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610aa9610aa462ffffff198816611541565b611578565b6000828152600284016020526040812060019055610ad4610acf62ffffff198816611610565b611631565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b0262ffffff198a16611673565b610b1162ffffff198b16611694565b600087815260018a016020526040902054610b3f610b3462ffffff198f166116b5565b62ffffff19166116f4565b6040518663ffffffff1660e01b8152600401610b5f959493929190612ceb565b600060405180830381600087803b158015610b7957600080fd5b505af1158015610b8d573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c605760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b610c6981611747565b50565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cd35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610d16908390869086906117cd16565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dc75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020610856918490849061122016565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ea65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b73ffffffffffffffffffffffffffffffffffffffff8116610f2f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610530565b610c69816117e1565b6000610f4382611858565b9150506000610f578262ffffff1916611979565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610fd45760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e000000006044820152606401610530565b6000610fe562ffffff19841661198d565b63ffffffff808416600090815260cc6020908152604080832054835260cb90915290208054929350918116908316116110605760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e74207374617465006044820152606401610530565b600061107162ffffff1986166119a1565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada91716110f6610b348a62ffffff19166119b6565b6040516111039190612d2b565b60405180910390a4505050505050565b60665473ffffffffffffffffffffffffffffffffffffffff1633146106e05760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610530565b8260005b602081101561121857600183821c1660008583602081106111a1576111a1612d3e565b60200201519050816001036111e157604080516020810183905290810185905260600160405160208183030381529060405280519060200120935061120e565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b505060010161117e565b509392505050565b600091825260029092016020526040902055565b60008054610100900460ff16156112d1578160ff1660011480156112575750303b155b6112c95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610530565b506000919050565b60005460ff80841691161061134e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610530565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114085760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b610c606119e9565b600061141e82610539611a6e565b92915050565b60008161143962ffffff198216610539611a92565b5061145b83611449856001611b93565b611454866002611b93565b6001611bc5565b91505b50919050565b60008161147a60015b62ffffff19831690611a92565b5061145b62ffffff19841660026004611be4565b60008161149b600161146d565b5061145b62ffffff198416602a6004611be4565b6000806114ca8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006114f48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b6000811580159061141e5750506001141590565b60008161152d600161146d565b5061145b62ffffff198416604e6004611be4565b60008161155662ffffff198216610539611a92565b5061145b83611566856002611b93565b611571866003611b93565b6002611bc5565b7f1dad5ea7bf29006ead0af41296d42c169129acd1ec64b3639ebe94b8c01bfa116115a862ffffff198316611c14565b6115b762ffffff198416611c42565b6115c662ffffff198516611c63565b6115d562ffffff198616611c84565b604080516bffffffffffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190a150565b60008161161d600161146d565b5061145b62ffffff198416602e6020611ca5565b600074010000000000000000000000000000000000000000820161166d57505060665473ffffffffffffffffffffffffffffffffffffffff1690565b8161141e565b600081611680600161146d565b5061145b62ffffff19841660266004611be4565b6000816116a1600161146d565b5061145b62ffffff19841660066020611ca5565b6000816116ca62ffffff198216610539611a92565b5061145b836116da856003611b93565b601886901c6bffffffffffffffffffffffff166003611bc5565b60606000806117118460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117368483602001611e63565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806118658382611a6e565b905060286bffffffffffffffffffffffff601883901c16116118c95760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610530565b6118f26118db62ffffff198316612008565b6118ed610b3462ffffff1985166119b6565b61201d565b915061192861190662ffffff198316611979565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6119745760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e207570646174657200000000000000006044820152606401610530565b915091565b600061141e62ffffff198316826004611be4565b600061141e62ffffff198316600480611be4565b600061141e62ffffff19831660086020611ca5565b600061141e60286119d981601886901c6bffffffffffffffffffffffff16612d6d565b62ffffff19851691906000612094565b600054610100900460ff16611a665760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b6106e061210e565b815160009060208401611a8964ffffffffff85168284612194565b95945050505050565b6000611a9e83836121db565b611b8c576000611abd611ab18560d81c90565b64ffffffffff166121fe565b9150506000611ad28464ffffffffff166121fe565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016105309190612d2b565b5090919050565b60006104846002836004811115611bac57611bac612c51565b611bb69190612d84565b62ffffff198516906002611be4565b6000611a8984611bd58186612d6d565b62ffffff198816919085612094565b6000611bf1826020612dc1565b611bfc906008612de4565b60ff16611c0a858585611ca5565b901c949350505050565b600081611c21600261146d565b50611c3562ffffff1984166002600c611be4565b63ffffffff169392505050565b600081611c4f600261146d565b50611c3562ffffff198416600e600c611be4565b600081611c70600261146d565b50611c3562ffffff198416601a600c611be4565b600081611c91600261146d565b50611c3562ffffff1984166026600c611be4565b60008160ff16600003611cba57506000610484565b611cd28460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611ced60ff841685612c39565b1115611d6557611d4c611d0e8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611d348660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166122e8565b60405162461bcd60e51b81526004016105309190612d2b565b60208260ff161115611ddf5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610530565b600882026000611dfd8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611ee05760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610530565b611ee983612356565b611f5b5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610530565b6000611f758460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611f9f8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611fc45760206060fd5b8285848460045afa50611ffe611fda8760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061141e62ffffff19831682602881612094565b60008061202f62ffffff1985166114af565b9050612088816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061060a8184612393565b6000806120af8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506120c8866123af565b846120d38784612c39565b6120dd9190612c39565b11156120f05762ffffff1991505061060a565b6120fa8582612c39565b9050611ffe8364ffffffffff168286612194565b600054610100900460ff1661218b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b6106e0336117e1565b6000806121a18385612c39565b90506040518111156121b1575060005b806000036121c65762ffffff19915050610484565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166121ef8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561227157600061221d826008612de4565b60ff1685901c905061222e816123f7565b61ffff16841793508160ff1660101461224957601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612204565b50600f5b60ff8160ff1610156122e257600061228e826008612de4565b60ff1685901c905061229f816123f7565b61ffff16831792508160ff166000146122ba57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612275565b50915091565b606060006122f5866121fe565b9150506000612303866121fe565b9150506000612311866121fe565b915050600061231f866121fe565b915050838383836040516020016123399493929190612e0d565b604051602081830303815290604052945050505050949350505050565b60006123628260d81c90565b64ffffffffff1664ffffffffff0361237c57506000919050565b6000612387836123af565b60405110199392505050565b60008060006123a28585612429565b9150915061121881612497565b60006123c98260181c6bffffffffffffffffffffffff1690565b6123e18360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061240960048360ff16901c612683565b60ff1661ffff919091161760081b61242082612683565b60ff1617919050565b600080825160410361245f5760208301516040840151606085015160001a612453878285856127ca565b94509450505050612490565b8251604003612488576020830151604084015161247d8683836128e2565b935093505050612490565b506000905060025b9250929050565b60008160048111156124ab576124ab612c51565b036124b35750565b60018160048111156124c7576124c7612c51565b036125145760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610530565b600281600481111561252857612528612c51565b036125755760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610530565b600381600481111561258957612589612c51565b036125fc5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610530565b600481600481111561261057612610612c51565b03610c695760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610530565b600060f08083179060ff8216900361269e5750603092915050565b8060ff1660f1036126b25750603192915050565b8060ff1660f2036126c65750603292915050565b8060ff1660f3036126da5750603392915050565b8060ff1660f4036126ee5750603492915050565b8060ff1660f5036127025750603592915050565b8060ff1660f6036127165750603692915050565b8060ff1660f70361272a5750603792915050565b8060ff1660f80361273e5750603892915050565b8060ff1660f9036127525750603992915050565b8060ff1660fa036127665750606192915050565b8060ff1660fb0361277a5750606292915050565b8060ff1660fc0361278e5750606392915050565b8060ff1660fd036127a25750606492915050565b8060ff1660fe036127b65750606592915050565b8060ff1660ff0361145e5750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561280157506000905060036128d9565b8460ff16601b1415801561281957508460ff16601c14155b1561282a57506000905060046128d9565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561287e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166128d2576000600192509250506128d9565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83168161291860ff86901c601b612c39565b9050612926878288856127ca565b935093505050935093915050565b803563ffffffff8116811461138657600080fd5b60008060006060848603121561295d57600080fd5b61296684612934565b925061297460208501612934565b9150604084013590509250925092565b60006020828403121561299657600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126129dd57600080fd5b813567ffffffffffffffff808211156129f8576129f861299d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612a3e57612a3e61299d565b81604052838152866020858801011115612a5757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806104608587031215612a8e57600080fd5b612a9785612934565b9350602085013567ffffffffffffffff811115612ab357600080fd5b612abf878288016129cc565b935050610440850186811115612ad457600080fd5b9396929550505060409290920191903590565b60008060408385031215612afa57600080fd5b612b0383612934565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610c6957600080fd5b60008060408385031215612b4657600080fd5b612b4f83612934565b91506020830135612b5f81612b11565b809150509250929050565b600060208284031215612b7c57600080fd5b813567ffffffffffffffff811115612b9357600080fd5b61060a848285016129cc565b600060208284031215612bb157600080fd5b813561048481612b11565b600080600060608486031215612bd157600080fd5b612bda84612934565b95602085013595506040909401359392505050565b600060208284031215612c0157600080fd5b61048482612934565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612c4c57612c4c612c0a565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612ca657602081850181015186830182015201612c8a565b81811115612cb8576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612d2060a0830184612c80565b979650505050505050565b6020815260006104846020830184612c80565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612d7f57612d7f612c0a565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612dbc57612dbc612c0a565b500290565b600060ff821660ff841680821015612ddb57612ddb612c0a565b90039392505050565b600060ff821660ff84168160ff0481118215151615612e0557612e05612c0a565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611ffe56fea26469706673582212205d5993c4cf83d07475fa6717cca8cd06d831ccd043b1312968f6776f42cd245664736f6c634300080d0033", + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// ReplicaManagerHarnessABI is the input ABI used to generate the binding from. -// Deprecated: Use ReplicaManagerHarnessMetaData.ABI instead. -var ReplicaManagerHarnessABI = ReplicaManagerHarnessMetaData.ABI +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { + return _ReplicaManagerHarness.Contract.ActiveReplicaNonce(&_ReplicaManagerHarness.CallOpts, _remoteDomain) +} -// Deprecated: Use ReplicaManagerHarnessMetaData.Sigs instead. -// ReplicaManagerHarnessFuncSigs maps the 4-byte function signature to its string representation. -var ReplicaManagerHarnessFuncSigs = ReplicaManagerHarnessMetaData.Sigs +// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// +// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { + return _ReplicaManagerHarness.Contract.ActiveReplicaNonce(&_ReplicaManagerHarness.CallOpts, _remoteDomain) +} -// ReplicaManagerHarnessBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ReplicaManagerHarnessMetaData.Bin instead. -var ReplicaManagerHarnessBin = ReplicaManagerHarnessMetaData.Bin +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "allGuards") -// DeployReplicaManagerHarness deploys a new Ethereum contract, binding an instance of ReplicaManagerHarness to it. -func DeployReplicaManagerHarness(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *ReplicaManagerHarness, error) { - parsed, err := ReplicaManagerHarnessMetaData.GetAbi() if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + return *new([]common.Address), err } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ReplicaManagerHarnessBin), backend, _localDomain) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &ReplicaManagerHarness{ReplicaManagerHarnessCaller: ReplicaManagerHarnessCaller{contract: contract}, ReplicaManagerHarnessTransactor: ReplicaManagerHarnessTransactor{contract: contract}, ReplicaManagerHarnessFilterer: ReplicaManagerHarnessFilterer{contract: contract}}, nil -} + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) -// ReplicaManagerHarness is an auto generated Go binding around an Ethereum contract. -type ReplicaManagerHarness struct { - ReplicaManagerHarnessCaller // Read-only binding to the contract - ReplicaManagerHarnessTransactor // Write-only binding to the contract - ReplicaManagerHarnessFilterer // Log filterer for contract events -} + return out0, err -// ReplicaManagerHarnessCaller is an auto generated read-only Go binding around an Ethereum contract. -type ReplicaManagerHarnessCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ReplicaManagerHarnessTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ReplicaManagerHarnessTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) AllGuards() ([]common.Address, error) { + return _ReplicaManagerHarness.Contract.AllGuards(&_ReplicaManagerHarness.CallOpts) } -// ReplicaManagerHarnessFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ReplicaManagerHarnessFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) AllGuards() ([]common.Address, error) { + return _ReplicaManagerHarness.Contract.AllGuards(&_ReplicaManagerHarness.CallOpts) } -// ReplicaManagerHarnessSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ReplicaManagerHarnessSession struct { - Contract *ReplicaManagerHarness // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "getGuard", _index) -// ReplicaManagerHarnessCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ReplicaManagerHarnessCallerSession struct { - Contract *ReplicaManagerHarnessCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} + if err != nil { + return *new(common.Address), err + } -// ReplicaManagerHarnessTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ReplicaManagerHarnessTransactorSession struct { - Contract *ReplicaManagerHarnessTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err -// ReplicaManagerHarnessRaw is an auto generated low-level Go binding around an Ethereum contract. -type ReplicaManagerHarnessRaw struct { - Contract *ReplicaManagerHarness // Generic contract binding to access the raw methods on } -// ReplicaManagerHarnessCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ReplicaManagerHarnessCallerRaw struct { - Contract *ReplicaManagerHarnessCaller // Generic read-only contract binding to access the raw methods on +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) GetGuard(_index *big.Int) (common.Address, error) { + return _ReplicaManagerHarness.Contract.GetGuard(&_ReplicaManagerHarness.CallOpts, _index) } -// ReplicaManagerHarnessTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ReplicaManagerHarnessTransactorRaw struct { - Contract *ReplicaManagerHarnessTransactor // Generic write-only contract binding to access the raw methods on +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _ReplicaManagerHarness.Contract.GetGuard(&_ReplicaManagerHarness.CallOpts, _index) } -// NewReplicaManagerHarness creates a new instance of ReplicaManagerHarness, bound to a specific deployed contract. -func NewReplicaManagerHarness(address common.Address, backend bind.ContractBackend) (*ReplicaManagerHarness, error) { - contract, err := bindReplicaManagerHarness(address, backend, backend, backend) +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "guardsAmount") + if err != nil { - return nil, err + return *new(*big.Int), err } - return &ReplicaManagerHarness{ReplicaManagerHarnessCaller: ReplicaManagerHarnessCaller{contract: contract}, ReplicaManagerHarnessTransactor: ReplicaManagerHarnessTransactor{contract: contract}, ReplicaManagerHarnessFilterer: ReplicaManagerHarnessFilterer{contract: contract}}, nil + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// NewReplicaManagerHarnessCaller creates a new read-only instance of ReplicaManagerHarness, bound to a specific deployed contract. -func NewReplicaManagerHarnessCaller(address common.Address, caller bind.ContractCaller) (*ReplicaManagerHarnessCaller, error) { - contract, err := bindReplicaManagerHarness(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &ReplicaManagerHarnessCaller{contract: contract}, nil +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) GuardsAmount() (*big.Int, error) { + return _ReplicaManagerHarness.Contract.GuardsAmount(&_ReplicaManagerHarness.CallOpts) } -// NewReplicaManagerHarnessTransactor creates a new write-only instance of ReplicaManagerHarness, bound to a specific deployed contract. -func NewReplicaManagerHarnessTransactor(address common.Address, transactor bind.ContractTransactor) (*ReplicaManagerHarnessTransactor, error) { - contract, err := bindReplicaManagerHarness(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ReplicaManagerHarnessTransactor{contract: contract}, nil +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) GuardsAmount() (*big.Int, error) { + return _ReplicaManagerHarness.Contract.GuardsAmount(&_ReplicaManagerHarness.CallOpts) } -// NewReplicaManagerHarnessFilterer creates a new log filterer instance of ReplicaManagerHarness, bound to a specific deployed contract. -func NewReplicaManagerHarnessFilterer(address common.Address, filterer bind.ContractFilterer) (*ReplicaManagerHarnessFilterer, error) { - contract, err := bindReplicaManagerHarness(address, nil, nil, filterer) +// IsNotary is a free data retrieval call binding the contract method 0xe98fae1f. +// +// Solidity: function isNotary(uint32 _domain, address _notary) view returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) IsNotary(opts *bind.CallOpts, _domain uint32, _notary common.Address) (bool, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "isNotary", _domain, _notary) + if err != nil { - return nil, err + return *new(bool), err } - return &ReplicaManagerHarnessFilterer{contract: contract}, nil + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + } -// bindReplicaManagerHarness binds a generic wrapper to an already deployed contract. -func bindReplicaManagerHarness(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ReplicaManagerHarnessABI)) +// IsNotary is a free data retrieval call binding the contract method 0xe98fae1f. +// +// Solidity: function isNotary(uint32 _domain, address _notary) view returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) IsNotary(_domain uint32, _notary common.Address) (bool, error) { + return _ReplicaManagerHarness.Contract.IsNotary(&_ReplicaManagerHarness.CallOpts, _domain, _notary) +} + +// IsNotary is a free data retrieval call binding the contract method 0xe98fae1f. +// +// Solidity: function isNotary(uint32 _domain, address _notary) view returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) IsNotary(_domain uint32, _notary common.Address) (bool, error) { + return _ReplicaManagerHarness.Contract.IsNotary(&_ReplicaManagerHarness.CallOpts, _domain, _notary) +} + +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "localDomain") + if err != nil { - return nil, err + return *new(uint32), err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ReplicaManagerHarness *ReplicaManagerHarnessRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaManagerHarness.Contract.ReplicaManagerHarnessCaller.contract.Call(opts, result, method, params...) + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ReplicaManagerHarness *ReplicaManagerHarnessRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.ReplicaManagerHarnessTransactor.contract.Transfer(opts) +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) LocalDomain() (uint32, error) { + return _ReplicaManagerHarness.Contract.LocalDomain(&_ReplicaManagerHarness.CallOpts) } -// Transact invokes the (paid) contract method with params as input values. -func (_ReplicaManagerHarness *ReplicaManagerHarnessRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.ReplicaManagerHarnessTransactor.contract.Transact(opts, method, params...) +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) LocalDomain() (uint32, error) { + return _ReplicaManagerHarness.Contract.LocalDomain(&_ReplicaManagerHarness.CallOpts) } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ReplicaManagerHarness.Contract.contract.Call(opts, result, method, params...) +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ReplicaManagerHarness.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.contract.Transfer(opts) +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Owner() (common.Address, error) { + return _ReplicaManagerHarness.Contract.Owner(&_ReplicaManagerHarness.CallOpts) } -// Transact invokes the (paid) contract method with params as input values. -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.contract.Transact(opts, method, params...) +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) Owner() (common.Address, error) { + return _ReplicaManagerHarness.Contract.Owner(&_ReplicaManagerHarness.CallOpts) } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. // -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) VERSION(opts *bind.CallOpts) (uint8, error) { +// Solidity: function sensitiveValue() view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) SensitiveValue(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "VERSION") + err := _ReplicaManagerHarness.contract.Call(opts, &out, "sensitiveValue") if err != nil { - return *new(uint8), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. // -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) VERSION() (uint8, error) { - return _ReplicaManagerHarness.Contract.VERSION(&_ReplicaManagerHarness.CallOpts) +// Solidity: function sensitiveValue() view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SensitiveValue() (*big.Int, error) { + return _ReplicaManagerHarness.Contract.SensitiveValue(&_ReplicaManagerHarness.CallOpts) } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. // -// Solidity: function VERSION() view returns(uint8) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) VERSION() (uint8, error) { - return _ReplicaManagerHarness.Contract.VERSION(&_ReplicaManagerHarness.CallOpts) +// Solidity: function sensitiveValue() view returns(uint256) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) SensitiveValue() (*big.Int, error) { + return _ReplicaManagerHarness.Contract.SensitiveValue(&_ReplicaManagerHarness.CallOpts) } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. // -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) AcceptableRoot(opts *bind.CallOpts, _remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "acceptableRoot", _remoteDomain, _optimisticSeconds, _root) + err := _ReplicaManagerHarness.contract.Call(opts, &out, "systemMessenger") if err != nil { - return *new(bool), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. // -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { - return _ReplicaManagerHarness.Contract.AcceptableRoot(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _optimisticSeconds, _root) +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SystemMessenger() (common.Address, error) { + return _ReplicaManagerHarness.Contract.SystemMessenger(&_ReplicaManagerHarness.CallOpts) } -// AcceptableRoot is a free data retrieval call binding the contract method 0x15a046aa. +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. // -// Solidity: function acceptableRoot(uint32 _remoteDomain, uint32 _optimisticSeconds, bytes32 _root) view returns(bool) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) AcceptableRoot(_remoteDomain uint32, _optimisticSeconds uint32, _root [32]byte) (bool, error) { - return _ReplicaManagerHarness.Contract.AcceptableRoot(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _optimisticSeconds, _root) +// Solidity: function systemMessenger() view returns(address) +func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) SystemMessenger() (common.Address, error) { + return _ReplicaManagerHarness.Contract.SystemMessenger(&_ReplicaManagerHarness.CallOpts) } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// AddNotary is a paid mutator transaction binding the contract method 0x2af678b0. // -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) ActiveReplicaConfirmedAt(opts *bind.CallOpts, _remoteDomain uint32, _root [32]byte) (*big.Int, error) { - var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "activeReplicaConfirmedAt", _remoteDomain, _root) +// Solidity: function addNotary(uint32 _domain, address _notary) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) AddNotary(opts *bind.TransactOpts, _domain uint32, _notary common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "addNotary", _domain, _notary) +} - if err != nil { - return *new(*big.Int), err - } +// AddNotary is a paid mutator transaction binding the contract method 0x2af678b0. +// +// Solidity: function addNotary(uint32 _domain, address _notary) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) AddNotary(_domain uint32, _notary common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.AddNotary(&_ReplicaManagerHarness.TransactOpts, _domain, _notary) +} - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) +// AddNotary is a paid mutator transaction binding the contract method 0x2af678b0. +// +// Solidity: function addNotary(uint32 _domain, address _notary) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) AddNotary(_domain uint32, _notary common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.AddNotary(&_ReplicaManagerHarness.TransactOpts, _domain, _notary) +} - return out0, err +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) Initialize(opts *bind.TransactOpts, _remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "initialize", _remoteDomain, _updater) +} +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. +// +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.Initialize(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _updater) } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. // -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { - return _ReplicaManagerHarness.Contract.ActiveReplicaConfirmedAt(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _root) +// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.Initialize(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _updater) } -// ActiveReplicaConfirmedAt is a free data retrieval call binding the contract method 0x7dfdba28. +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. // -// Solidity: function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root) view returns(uint256) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) ActiveReplicaConfirmedAt(_remoteDomain uint32, _root [32]byte) (*big.Int, error) { - return _ReplicaManagerHarness.Contract.ActiveReplicaConfirmedAt(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _root) +// Solidity: function process(bytes _message) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) Process(opts *bind.TransactOpts, _message []byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "process", _message) } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. // -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) ActiveReplicaMessageStatus(opts *bind.CallOpts, _remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "activeReplicaMessageStatus", _remoteDomain, _messageId) +// Solidity: function process(bytes _message) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Process(_message []byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.Process(&_ReplicaManagerHarness.TransactOpts, _message) +} - if err != nil { - return *new([32]byte), err - } +// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// +// Solidity: function process(bytes _message) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) Process(_message []byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.Process(&_ReplicaManagerHarness.TransactOpts, _message) +} - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) Prove(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "prove", _remoteDomain, _message, _proof, _index) +} - return out0, err +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.Prove(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _message, _proof, _index) +} +// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// +// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.Prove(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _message, _proof, _index) } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. // -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - return _ReplicaManagerHarness.Contract.ActiveReplicaMessageStatus(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _messageId) +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) ProveAndProcess(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "proveAndProcess", _remoteDomain, _message, _proof, _index) } -// ActiveReplicaMessageStatus is a free data retrieval call binding the contract method 0x63415514. +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. // -// Solidity: function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId) view returns(bytes32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) ActiveReplicaMessageStatus(_remoteDomain uint32, _messageId [32]byte) ([32]byte, error) { - return _ReplicaManagerHarness.Contract.ActiveReplicaMessageStatus(&_ReplicaManagerHarness.CallOpts, _remoteDomain, _messageId) +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.ProveAndProcess(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _message, _proof, _index) } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. // -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) ActiveReplicaNonce(opts *bind.CallOpts, _remoteDomain uint32) (uint32, error) { - var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "activeReplicaNonce", _remoteDomain) +// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.ProveAndProcess(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _message, _proof, _index) +} - if err != nil { - return *new(uint32), err - } +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "renounceOwnership") +} - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) RenounceOwnership() (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.RenounceOwnership(&_ReplicaManagerHarness.TransactOpts) +} - return out0, err +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.RenounceOwnership(&_ReplicaManagerHarness.TransactOpts) +} + +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. +// +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetConfirmation(opts *bind.TransactOpts, _remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "setConfirmation", _remoteDomain, _root, _confirmAt) +} +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. +// +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetConfirmation(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _root, _confirmAt) } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. // -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { - return _ReplicaManagerHarness.Contract.ActiveReplicaNonce(&_ReplicaManagerHarness.CallOpts, _remoteDomain) +// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetConfirmation(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _root, _confirmAt) } -// ActiveReplicaNonce is a free data retrieval call binding the contract method 0xb65672d3. +// SetMessageStatus is a paid mutator transaction binding the contract method 0xbfd84d36. // -// Solidity: function activeReplicaNonce(uint32 _remoteDomain) view returns(uint32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) ActiveReplicaNonce(_remoteDomain uint32) (uint32, error) { - return _ReplicaManagerHarness.Contract.ActiveReplicaNonce(&_ReplicaManagerHarness.CallOpts, _remoteDomain) +// Solidity: function setMessageStatus(uint32 _remoteDomain, bytes32 _messageHash, bytes32 _status) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetMessageStatus(opts *bind.TransactOpts, _remoteDomain uint32, _messageHash [32]byte, _status [32]byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "setMessageStatus", _remoteDomain, _messageHash, _status) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// SetMessageStatus is a paid mutator transaction binding the contract method 0xbfd84d36. // -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "localDomain") +// Solidity: function setMessageStatus(uint32 _remoteDomain, bytes32 _messageHash, bytes32 _status) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetMessageStatus(_remoteDomain uint32, _messageHash [32]byte, _status [32]byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetMessageStatus(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _messageHash, _status) +} - if err != nil { - return *new(uint32), err - } +// SetMessageStatus is a paid mutator transaction binding the contract method 0xbfd84d36. +// +// Solidity: function setMessageStatus(uint32 _remoteDomain, bytes32 _messageHash, bytes32 _status) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetMessageStatus(_remoteDomain uint32, _messageHash [32]byte, _status [32]byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetMessageStatus(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _messageHash, _status) +} - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) +// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. +// +// Solidity: function setSensitiveValue(uint256 _newValue) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetSensitiveValue(opts *bind.TransactOpts, _newValue *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "setSensitiveValue", _newValue) +} - return out0, err +// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. +// +// Solidity: function setSensitiveValue(uint256 _newValue) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetSensitiveValue(_newValue *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetSensitiveValue(&_ReplicaManagerHarness.TransactOpts, _newValue) +} +// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. +// +// Solidity: function setSensitiveValue(uint256 _newValue) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetSensitiveValue(_newValue *big.Int) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetSensitiveValue(&_ReplicaManagerHarness.TransactOpts, _newValue) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. // -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) LocalDomain() (uint32, error) { - return _ReplicaManagerHarness.Contract.LocalDomain(&_ReplicaManagerHarness.CallOpts) +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "setSystemMessenger", _systemMessenger) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. // -// Solidity: function localDomain() view returns(uint32) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) LocalDomain() (uint32, error) { - return _ReplicaManagerHarness.Contract.LocalDomain(&_ReplicaManagerHarness.CallOpts) +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetSystemMessenger(&_ReplicaManagerHarness.TransactOpts, _systemMessenger) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. // -// Solidity: function owner() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "owner") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetSystemMessenger(&_ReplicaManagerHarness.TransactOpts, _systemMessenger) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. // -// Solidity: function owner() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Owner() (common.Address, error) { - return _ReplicaManagerHarness.Contract.Owner(&_ReplicaManagerHarness.CallOpts) +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetUpdater(opts *bind.TransactOpts, _domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "setUpdater", _domain, _updater) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. // -// Solidity: function owner() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) Owner() (common.Address, error) { - return _ReplicaManagerHarness.Contract.Owner(&_ReplicaManagerHarness.CallOpts) +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetUpdater(_domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetUpdater(&_ReplicaManagerHarness.TransactOpts, _domain, _updater) } -// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// SetUpdater is a paid mutator transaction binding the contract method 0x61bc3111. // -// Solidity: function sensitiveValue() view returns(uint256) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) SensitiveValue(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "sensitiveValue") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - +// Solidity: function setUpdater(uint32 _domain, address _updater) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetUpdater(_domain uint32, _updater common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SetUpdater(&_ReplicaManagerHarness.TransactOpts, _domain, _updater) } -// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. // -// Solidity: function sensitiveValue() view returns(uint256) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SensitiveValue() (*big.Int, error) { - return _ReplicaManagerHarness.Contract.SensitiveValue(&_ReplicaManagerHarness.CallOpts) +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SubmitAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "submitAttestation", _attestation) } -// SensitiveValue is a free data retrieval call binding the contract method 0x089d2894. +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. // -// Solidity: function sensitiveValue() view returns(uint256) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) SensitiveValue() (*big.Int, error) { - return _ReplicaManagerHarness.Contract.SensitiveValue(&_ReplicaManagerHarness.CallOpts) +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SubmitAttestation(&_ReplicaManagerHarness.TransactOpts, _attestation) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. // -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "systemMessenger") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +// Solidity: function submitAttestation(bytes _attestation) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.SubmitAttestation(&_ReplicaManagerHarness.TransactOpts, _attestation) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SystemMessenger() (common.Address, error) { - return _ReplicaManagerHarness.Contract.SystemMessenger(&_ReplicaManagerHarness.CallOpts) +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.contract.Transact(opts, "transferOwnership", newOwner) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function systemMessenger() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) SystemMessenger() (common.Address, error) { - return _ReplicaManagerHarness.Contract.SystemMessenger(&_ReplicaManagerHarness.CallOpts) +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.TransferOwnership(&_ReplicaManagerHarness.TransactOpts, newOwner) } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // -// Solidity: function updater() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _ReplicaManagerHarness.contract.Call(opts, &out, "updater") - - if err != nil { - return *new(common.Address), err - } +// Solidity: function transferOwnership(address newOwner) returns() +func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ReplicaManagerHarness.Contract.TransferOwnership(&_ReplicaManagerHarness.TransactOpts, newOwner) +} - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) +// ReplicaManagerHarnessAttestationAcceptedIterator is returned from FilterAttestationAccepted and is used to iterate over the raw logs and unpacked data for AttestationAccepted events raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessAttestationAcceptedIterator struct { + Event *ReplicaManagerHarnessAttestationAccepted // Event containing the contract specifics and raw log - return out0, err + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Updater() (common.Address, error) { - return _ReplicaManagerHarness.Contract.Updater(&_ReplicaManagerHarness.CallOpts) -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerHarnessAttestationAcceptedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerHarnessAttestationAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_ReplicaManagerHarness *ReplicaManagerHarnessCallerSession) Updater() (common.Address, error) { - return _ReplicaManagerHarness.Contract.Updater(&_ReplicaManagerHarness.CallOpts) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerHarnessAttestationAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. -// -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) Initialize(opts *bind.TransactOpts, _remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "initialize", _remoteDomain, _updater) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. -// -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.Initialize(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _updater) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerHarnessAttestationAcceptedIterator) Error() error { + return it.fail } -// Initialize is a paid mutator transaction binding the contract method 0x8624c35c. -// -// Solidity: function initialize(uint32 _remoteDomain, address _updater) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) Initialize(_remoteDomain uint32, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.Initialize(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _updater) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerHarnessAttestationAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. -// -// Solidity: function process(bytes _message) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) Process(opts *bind.TransactOpts, _message []byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "process", _message) +// ReplicaManagerHarnessAttestationAccepted represents a AttestationAccepted event raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessAttestationAccepted struct { + HomeDomain uint32 + Nonce uint32 + Root [32]byte + Signature []byte + Raw types.Log // Blockchain specific contextual infos } -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. +// FilterAttestationAccepted is a free log retrieval operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. // -// Solidity: function process(bytes _message) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Process(_message []byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.Process(&_ReplicaManagerHarness.TransactOpts, _message) -} +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterAttestationAccepted(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*ReplicaManagerHarnessAttestationAcceptedIterator, error) { -// Process is a paid mutator transaction binding the contract method 0x928bc4b2. -// -// Solidity: function process(bytes _message) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) Process(_message []byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.Process(&_ReplicaManagerHarness.TransactOpts, _message) -} + var homeDomainRule []interface{} + for _, homeDomainItem := range homeDomain { + homeDomainRule = append(homeDomainRule, homeDomainItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var rootRule []interface{} + for _, rootItem := range root { + rootRule = append(rootRule, rootItem) + } -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. -// -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) Prove(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "prove", _remoteDomain, _message, _proof, _index) + logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "AttestationAccepted", homeDomainRule, nonceRule, rootRule) + if err != nil { + return nil, err + } + return &ReplicaManagerHarnessAttestationAcceptedIterator{contract: _ReplicaManagerHarness.contract, event: "AttestationAccepted", logs: logs, sub: sub}, nil } -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. +// WatchAttestationAccepted is a free log subscription operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. // -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.Prove(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _message, _proof, _index) -} +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchAttestationAccepted(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessAttestationAccepted, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { + + var homeDomainRule []interface{} + for _, homeDomainItem := range homeDomain { + homeDomainRule = append(homeDomainRule, homeDomainItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + var rootRule []interface{} + for _, rootItem := range root { + rootRule = append(rootRule, rootItem) + } + + logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "AttestationAccepted", homeDomainRule, nonceRule, rootRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerHarnessAttestationAccepted) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "AttestationAccepted", log); err != nil { + return err + } + event.Raw = log -// Prove is a paid mutator transaction binding the contract method 0x4f63be3f. -// -// Solidity: function prove(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns(bool) -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) Prove(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.Prove(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _message, _proof, _index) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. +// ParseAttestationAccepted is a log parse operation binding the contract event 0x04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb. // -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) ProveAndProcess(opts *bind.TransactOpts, _remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "proveAndProcess", _remoteDomain, _message, _proof, _index) +// Solidity: event AttestationAccepted(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseAttestationAccepted(log types.Log) (*ReplicaManagerHarnessAttestationAccepted, error) { + event := new(ReplicaManagerHarnessAttestationAccepted) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "AttestationAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. -// -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.ProveAndProcess(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _message, _proof, _index) -} +// ReplicaManagerHarnessGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessGuardAddedIterator struct { + Event *ReplicaManagerHarnessGuardAdded // Event containing the contract specifics and raw log -// ProveAndProcess is a paid mutator transaction binding the contract method 0x68705275. -// -// Solidity: function proveAndProcess(uint32 _remoteDomain, bytes _message, bytes32[32] _proof, uint256 _index) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) ProveAndProcess(_remoteDomain uint32, _message []byte, _proof [32][32]byte, _index *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.ProveAndProcess(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _message, _proof, _index) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "renounceOwnership") + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) RenounceOwnership() (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.RenounceOwnership(&_ReplicaManagerHarness.TransactOpts) -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerHarnessGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerHarnessGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.RenounceOwnership(&_ReplicaManagerHarness.TransactOpts) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerHarnessGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetConfirmation(opts *bind.TransactOpts, _remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "setConfirmation", _remoteDomain, _root, _confirmAt) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetConfirmation(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _root, _confirmAt) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerHarnessGuardAddedIterator) Error() error { + return it.fail } -// SetConfirmation is a paid mutator transaction binding the contract method 0x9df7d36d. -// -// Solidity: function setConfirmation(uint32 _remoteDomain, bytes32 _root, uint256 _confirmAt) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetConfirmation(_remoteDomain uint32, _root [32]byte, _confirmAt *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetConfirmation(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _root, _confirmAt) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerHarnessGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// SetMessageStatus is a paid mutator transaction binding the contract method 0xbfd84d36. -// -// Solidity: function setMessageStatus(uint32 _remoteDomain, bytes32 _messageHash, bytes32 _status) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetMessageStatus(opts *bind.TransactOpts, _remoteDomain uint32, _messageHash [32]byte, _status [32]byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "setMessageStatus", _remoteDomain, _messageHash, _status) +// ReplicaManagerHarnessGuardAdded represents a GuardAdded event raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// SetMessageStatus is a paid mutator transaction binding the contract method 0xbfd84d36. +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function setMessageStatus(uint32 _remoteDomain, bytes32 _messageHash, bytes32 _status) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetMessageStatus(_remoteDomain uint32, _messageHash [32]byte, _status [32]byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetMessageStatus(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _messageHash, _status) -} +// Solidity: event GuardAdded(address guard) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*ReplicaManagerHarnessGuardAddedIterator, error) { -// SetMessageStatus is a paid mutator transaction binding the contract method 0xbfd84d36. -// -// Solidity: function setMessageStatus(uint32 _remoteDomain, bytes32 _messageHash, bytes32 _status) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetMessageStatus(_remoteDomain uint32, _messageHash [32]byte, _status [32]byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetMessageStatus(&_ReplicaManagerHarness.TransactOpts, _remoteDomain, _messageHash, _status) + logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return &ReplicaManagerHarnessGuardAddedIterator{contract: _ReplicaManagerHarness.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function setSensitiveValue(uint256 _newValue) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetSensitiveValue(opts *bind.TransactOpts, _newValue *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "setSensitiveValue", _newValue) -} +// Solidity: event GuardAdded(address guard) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessGuardAdded) (event.Subscription, error) { -// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. -// -// Solidity: function setSensitiveValue(uint256 _newValue) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetSensitiveValue(_newValue *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetSensitiveValue(&_ReplicaManagerHarness.TransactOpts, _newValue) -} + logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerHarnessGuardAdded) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log -// SetSensitiveValue is a paid mutator transaction binding the contract method 0x48639d24. -// -// Solidity: function setSensitiveValue(uint256 _newValue) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetSensitiveValue(_newValue *big.Int) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetSensitiveValue(&_ReplicaManagerHarness.TransactOpts, _newValue) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +// Solidity: event GuardAdded(address guard) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseGuardAdded(log types.Log) (*ReplicaManagerHarnessGuardAdded, error) { + event := new(ReplicaManagerHarnessGuardAdded) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetSystemMessenger(&_ReplicaManagerHarness.TransactOpts, _systemMessenger) -} +// ReplicaManagerHarnessGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessGuardRemovedIterator struct { + Event *ReplicaManagerHarnessGuardRemoved // Event containing the contract specifics and raw log -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetSystemMessenger(&_ReplicaManagerHarness.TransactOpts, _systemMessenger) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "setUpdater", _updater) + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetUpdater(&_ReplicaManagerHarness.TransactOpts, _updater) -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ReplicaManagerHarnessGuardRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerHarnessGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SetUpdater(&_ReplicaManagerHarness.TransactOpts, _updater) + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ReplicaManagerHarnessGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) SubmitAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "submitAttestation", _attestation) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ReplicaManagerHarnessGuardRemovedIterator) Error() error { + return it.fail } -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SubmitAttestation(&_ReplicaManagerHarness.TransactOpts, _attestation) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ReplicaManagerHarnessGuardRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// SubmitAttestation is a paid mutator transaction binding the contract method 0xf646a512. -// -// Solidity: function submitAttestation(bytes _attestation) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) SubmitAttestation(_attestation []byte) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.SubmitAttestation(&_ReplicaManagerHarness.TransactOpts, _attestation) +// ReplicaManagerHarnessGuardRemoved represents a GuardRemoved event raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.contract.Transact(opts, "transferOwnership", newOwner) +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*ReplicaManagerHarnessGuardRemovedIterator, error) { + + logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return &ReplicaManagerHarnessGuardRemovedIterator{contract: _ReplicaManagerHarness.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.TransferOwnership(&_ReplicaManagerHarness.TransactOpts, newOwner) +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessGuardRemoved) (event.Subscription, error) { + + logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "GuardRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ReplicaManagerHarnessGuardRemoved) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_ReplicaManagerHarness *ReplicaManagerHarnessTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _ReplicaManagerHarness.Contract.TransferOwnership(&_ReplicaManagerHarness.TransactOpts, newOwner) +// Solidity: event GuardRemoved(address guard) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseGuardRemoved(log types.Log) (*ReplicaManagerHarnessGuardRemoved, error) { + event := new(ReplicaManagerHarnessGuardRemoved) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } // ReplicaManagerHarnessInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ReplicaManagerHarness contract. @@ -5695,9 +8061,9 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseLogTips(log ty return event, nil } -// ReplicaManagerHarnessNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessNewUpdaterIterator struct { - Event *ReplicaManagerHarnessNewUpdater // Event containing the contract specifics and raw log +// ReplicaManagerHarnessNotaryAddedIterator is returned from FilterNotaryAdded and is used to iterate over the raw logs and unpacked data for NotaryAdded events raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessNotaryAddedIterator struct { + Event *ReplicaManagerHarnessNotaryAdded // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -5711,7 +8077,7 @@ type ReplicaManagerHarnessNewUpdaterIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerHarnessNewUpdaterIterator) Next() bool { +func (it *ReplicaManagerHarnessNotaryAddedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -5720,7 +8086,7 @@ func (it *ReplicaManagerHarnessNewUpdaterIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessNewUpdater) + it.Event = new(ReplicaManagerHarnessNotaryAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5735,7 +8101,7 @@ func (it *ReplicaManagerHarnessNewUpdaterIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessNewUpdater) + it.Event = new(ReplicaManagerHarnessNotaryAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5751,42 +8117,52 @@ func (it *ReplicaManagerHarnessNewUpdaterIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerHarnessNewUpdaterIterator) Error() error { +func (it *ReplicaManagerHarnessNotaryAddedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerHarnessNewUpdaterIterator) Close() error { +func (it *ReplicaManagerHarnessNotaryAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerHarnessNewUpdater represents a NewUpdater event raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerHarnessNotaryAdded represents a NotaryAdded event raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessNotaryAdded struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// FilterNotaryAdded is a free log retrieval operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*ReplicaManagerHarnessNewUpdaterIterator, error) { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterNotaryAdded(opts *bind.FilterOpts, domain []uint32) (*ReplicaManagerHarnessNotaryAddedIterator, error) { + + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } - logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "NewUpdater") + logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "NotaryAdded", domainRule) if err != nil { return nil, err } - return &ReplicaManagerHarnessNewUpdaterIterator{contract: _ReplicaManagerHarness.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &ReplicaManagerHarnessNotaryAddedIterator{contract: _ReplicaManagerHarness.contract, event: "NotaryAdded", logs: logs, sub: sub}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// WatchNotaryAdded is a free log subscription operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessNewUpdater) (event.Subscription, error) { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchNotaryAdded(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessNotaryAdded, domain []uint32) (event.Subscription, error) { - logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "NewUpdater") + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) + } + + logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "NotaryAdded", domainRule) if err != nil { return nil, err } @@ -5796,8 +8172,8 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchNewUpdater(opt select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerHarnessNewUpdater) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "NewUpdater", log); err != nil { + event := new(ReplicaManagerHarnessNotaryAdded) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "NotaryAdded", log); err != nil { return err } event.Raw = log @@ -5818,21 +8194,21 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchNewUpdater(opt }), nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// ParseNotaryAdded is a log parse operation binding the contract event 0x62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseNewUpdater(log types.Log) (*ReplicaManagerHarnessNewUpdater, error) { - event := new(ReplicaManagerHarnessNewUpdater) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// Solidity: event NotaryAdded(uint32 indexed domain, address notary) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseNotaryAdded(log types.Log) (*ReplicaManagerHarnessNotaryAdded, error) { + event := new(ReplicaManagerHarnessNotaryAdded) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "NotaryAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerHarnessOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessOwnershipTransferredIterator struct { - Event *ReplicaManagerHarnessOwnershipTransferred // Event containing the contract specifics and raw log +// ReplicaManagerHarnessNotaryRemovedIterator is returned from FilterNotaryRemoved and is used to iterate over the raw logs and unpacked data for NotaryRemoved events raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessNotaryRemovedIterator struct { + Event *ReplicaManagerHarnessNotaryRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -5846,7 +8222,7 @@ type ReplicaManagerHarnessOwnershipTransferredIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Next() bool { +func (it *ReplicaManagerHarnessNotaryRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -5855,7 +8231,7 @@ func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessOwnershipTransferred) + it.Event = new(ReplicaManagerHarnessNotaryRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5870,7 +8246,7 @@ func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessOwnershipTransferred) + it.Event = new(ReplicaManagerHarnessNotaryRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5886,60 +8262,52 @@ func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Error() error { +func (it *ReplicaManagerHarnessNotaryRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Close() error { +func (it *ReplicaManagerHarnessNotaryRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerHarnessOwnershipTransferred represents a OwnershipTransferred event raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerHarnessNotaryRemoved represents a NotaryRemoved event raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessNotaryRemoved struct { + Domain uint32 + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// FilterNotaryRemoved is a free log retrieval operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ReplicaManagerHarnessOwnershipTransferredIterator, error) { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterNotaryRemoved(opts *bind.FilterOpts, domain []uint32) (*ReplicaManagerHarnessNotaryRemovedIterator, error) { - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) } - logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "NotaryRemoved", domainRule) if err != nil { return nil, err } - return &ReplicaManagerHarnessOwnershipTransferredIterator{contract: _ReplicaManagerHarness.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &ReplicaManagerHarnessNotaryRemovedIterator{contract: _ReplicaManagerHarness.contract, event: "NotaryRemoved", logs: logs, sub: sub}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// WatchNotaryRemoved is a free log subscription operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchNotaryRemoved(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessNotaryRemoved, domain []uint32) (event.Subscription, error) { - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) + var domainRule []interface{} + for _, domainItem := range domain { + domainRule = append(domainRule, domainItem) } - logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "NotaryRemoved", domainRule) if err != nil { return nil, err } @@ -5949,8 +8317,8 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchOwnershipTrans select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerHarnessOwnershipTransferred) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(ReplicaManagerHarnessNotaryRemoved) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { return err } event.Raw = log @@ -5971,21 +8339,21 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchOwnershipTrans }), nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// ParseNotaryRemoved is a log parse operation binding the contract event 0x3e006f5b97c04e82df349064761281b0981d45330c2f3e57cc032203b0e31b6b. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseOwnershipTransferred(log types.Log) (*ReplicaManagerHarnessOwnershipTransferred, error) { - event := new(ReplicaManagerHarnessOwnershipTransferred) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// Solidity: event NotaryRemoved(uint32 indexed domain, address notary) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseNotaryRemoved(log types.Log) (*ReplicaManagerHarnessNotaryRemoved, error) { + event := new(ReplicaManagerHarnessNotaryRemoved) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "NotaryRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerHarnessProcessIterator is returned from FilterProcess and is used to iterate over the raw logs and unpacked data for Process events raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessProcessIterator struct { - Event *ReplicaManagerHarnessProcess // Event containing the contract specifics and raw log +// ReplicaManagerHarnessOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessOwnershipTransferredIterator struct { + Event *ReplicaManagerHarnessOwnershipTransferred // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -5999,7 +8367,7 @@ type ReplicaManagerHarnessProcessIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerHarnessProcessIterator) Next() bool { +func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -6008,7 +8376,7 @@ func (it *ReplicaManagerHarnessProcessIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessProcess) + it.Event = new(ReplicaManagerHarnessOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -6023,7 +8391,7 @@ func (it *ReplicaManagerHarnessProcessIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessProcess) + it.Event = new(ReplicaManagerHarnessOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -6039,60 +8407,60 @@ func (it *ReplicaManagerHarnessProcessIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerHarnessProcessIterator) Error() error { +func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerHarnessProcessIterator) Close() error { +func (it *ReplicaManagerHarnessOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerHarnessProcess represents a Process event raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessProcess struct { - RemoteDomain uint32 - MessageHash [32]byte - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerHarnessOwnershipTransferred represents a OwnershipTransferred event raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterProcess is a free log retrieval operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterProcess(opts *bind.FilterOpts, remoteDomain []uint32, messageHash [][32]byte) (*ReplicaManagerHarnessProcessIterator, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ReplicaManagerHarnessOwnershipTransferredIterator, error) { - var remoteDomainRule []interface{} - for _, remoteDomainItem := range remoteDomain { - remoteDomainRule = append(remoteDomainRule, remoteDomainItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "Process", remoteDomainRule, messageHashRule) + logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } - return &ReplicaManagerHarnessProcessIterator{contract: _ReplicaManagerHarness.contract, event: "Process", logs: logs, sub: sub}, nil + return &ReplicaManagerHarnessOwnershipTransferredIterator{contract: _ReplicaManagerHarness.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// WatchProcess is a free log subscription operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchProcess(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessProcess, remoteDomain []uint32, messageHash [][32]byte) (event.Subscription, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - var remoteDomainRule []interface{} - for _, remoteDomainItem := range remoteDomain { - remoteDomainRule = append(remoteDomainRule, remoteDomainItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "Process", remoteDomainRule, messageHashRule) + logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } @@ -6102,8 +8470,8 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchProcess(opts * select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerHarnessProcess) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "Process", log); err != nil { + event := new(ReplicaManagerHarnessOwnershipTransferred) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -6124,21 +8492,21 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchProcess(opts * }), nil } -// ParseProcess is a log parse operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseProcess(log types.Log) (*ReplicaManagerHarnessProcess, error) { - event := new(ReplicaManagerHarnessProcess) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "Process", log); err != nil { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseOwnershipTransferred(log types.Log) (*ReplicaManagerHarnessOwnershipTransferred, error) { + event := new(ReplicaManagerHarnessOwnershipTransferred) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerHarnessSetConfirmationIterator is returned from FilterSetConfirmation and is used to iterate over the raw logs and unpacked data for SetConfirmation events raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessSetConfirmationIterator struct { - Event *ReplicaManagerHarnessSetConfirmation // Event containing the contract specifics and raw log +// ReplicaManagerHarnessProcessIterator is returned from FilterProcess and is used to iterate over the raw logs and unpacked data for Process events raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessProcessIterator struct { + Event *ReplicaManagerHarnessProcess // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -6152,7 +8520,7 @@ type ReplicaManagerHarnessSetConfirmationIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerHarnessSetConfirmationIterator) Next() bool { +func (it *ReplicaManagerHarnessProcessIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -6161,7 +8529,7 @@ func (it *ReplicaManagerHarnessSetConfirmationIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessSetConfirmation) + it.Event = new(ReplicaManagerHarnessProcess) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -6176,7 +8544,7 @@ func (it *ReplicaManagerHarnessSetConfirmationIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessSetConfirmation) + it.Event = new(ReplicaManagerHarnessProcess) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -6192,62 +8560,60 @@ func (it *ReplicaManagerHarnessSetConfirmationIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerHarnessSetConfirmationIterator) Error() error { +func (it *ReplicaManagerHarnessProcessIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerHarnessSetConfirmationIterator) Close() error { +func (it *ReplicaManagerHarnessProcessIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerHarnessSetConfirmation represents a SetConfirmation event raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessSetConfirmation struct { - RemoteDomain uint32 - Root [32]byte - PreviousConfirmAt *big.Int - NewConfirmAt *big.Int - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerHarnessProcess represents a Process event raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessProcess struct { + RemoteDomain uint32 + MessageHash [32]byte + Raw types.Log // Blockchain specific contextual infos } -// FilterSetConfirmation is a free log retrieval operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// FilterProcess is a free log retrieval operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. // -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterSetConfirmation(opts *bind.FilterOpts, remoteDomain []uint32, root [][32]byte) (*ReplicaManagerHarnessSetConfirmationIterator, error) { +// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterProcess(opts *bind.FilterOpts, remoteDomain []uint32, messageHash [][32]byte) (*ReplicaManagerHarnessProcessIterator, error) { var remoteDomainRule []interface{} for _, remoteDomainItem := range remoteDomain { remoteDomainRule = append(remoteDomainRule, remoteDomainItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) } - logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) + logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "Process", remoteDomainRule, messageHashRule) if err != nil { return nil, err } - return &ReplicaManagerHarnessSetConfirmationIterator{contract: _ReplicaManagerHarness.contract, event: "SetConfirmation", logs: logs, sub: sub}, nil + return &ReplicaManagerHarnessProcessIterator{contract: _ReplicaManagerHarness.contract, event: "Process", logs: logs, sub: sub}, nil } -// WatchSetConfirmation is a free log subscription operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. +// WatchProcess is a free log subscription operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. // -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchSetConfirmation(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessSetConfirmation, remoteDomain []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchProcess(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessProcess, remoteDomain []uint32, messageHash [][32]byte) (event.Subscription, error) { var remoteDomainRule []interface{} for _, remoteDomainItem := range remoteDomain { remoteDomainRule = append(remoteDomainRule, remoteDomainItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) } - logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) + logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "Process", remoteDomainRule, messageHashRule) if err != nil { return nil, err } @@ -6257,8 +8623,8 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchSetConfirmatio select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerHarnessSetConfirmation) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "SetConfirmation", log); err != nil { + event := new(ReplicaManagerHarnessProcess) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "Process", log); err != nil { return err } event.Raw = log @@ -6279,21 +8645,21 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchSetConfirmatio }), nil } -// ParseSetConfirmation is a log parse operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. -// -// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseSetConfirmation(log types.Log) (*ReplicaManagerHarnessSetConfirmation, error) { - event := new(ReplicaManagerHarnessSetConfirmation) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "SetConfirmation", log); err != nil { +// ParseProcess is a log parse operation binding the contract event 0x321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af. +// +// Solidity: event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseProcess(log types.Log) (*ReplicaManagerHarnessProcess, error) { + event := new(ReplicaManagerHarnessProcess) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "Process", log); err != nil { return nil, err } event.Raw = log return event, nil } -// ReplicaManagerHarnessUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessUpdateIterator struct { - Event *ReplicaManagerHarnessUpdate // Event containing the contract specifics and raw log +// ReplicaManagerHarnessSetConfirmationIterator is returned from FilterSetConfirmation and is used to iterate over the raw logs and unpacked data for SetConfirmation events raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessSetConfirmationIterator struct { + Event *ReplicaManagerHarnessSetConfirmation // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -6307,7 +8673,7 @@ type ReplicaManagerHarnessUpdateIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *ReplicaManagerHarnessUpdateIterator) Next() bool { +func (it *ReplicaManagerHarnessSetConfirmationIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -6316,7 +8682,7 @@ func (it *ReplicaManagerHarnessUpdateIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessUpdate) + it.Event = new(ReplicaManagerHarnessSetConfirmation) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -6331,7 +8697,7 @@ func (it *ReplicaManagerHarnessUpdateIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(ReplicaManagerHarnessUpdate) + it.Event = new(ReplicaManagerHarnessSetConfirmation) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -6347,70 +8713,62 @@ func (it *ReplicaManagerHarnessUpdateIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *ReplicaManagerHarnessUpdateIterator) Error() error { +func (it *ReplicaManagerHarnessSetConfirmationIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *ReplicaManagerHarnessUpdateIterator) Close() error { +func (it *ReplicaManagerHarnessSetConfirmationIterator) Close() error { it.sub.Unsubscribe() return nil } -// ReplicaManagerHarnessUpdate represents a Update event raised by the ReplicaManagerHarness contract. -type ReplicaManagerHarnessUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// ReplicaManagerHarnessSetConfirmation represents a SetConfirmation event raised by the ReplicaManagerHarness contract. +type ReplicaManagerHarnessSetConfirmation struct { + RemoteDomain uint32 + Root [32]byte + PreviousConfirmAt *big.Int + NewConfirmAt *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// FilterSetConfirmation is a free log retrieval operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*ReplicaManagerHarnessUpdateIterator, error) { +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) FilterSetConfirmation(opts *bind.FilterOpts, remoteDomain []uint32, root [][32]byte) (*ReplicaManagerHarnessSetConfirmationIterator, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var remoteDomainRule []interface{} + for _, remoteDomainItem := range remoteDomain { + remoteDomainRule = append(remoteDomainRule, remoteDomainItem) } var rootRule []interface{} for _, rootItem := range root { rootRule = append(rootRule, rootItem) } - logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _ReplicaManagerHarness.contract.FilterLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) if err != nil { return nil, err } - return &ReplicaManagerHarnessUpdateIterator{contract: _ReplicaManagerHarness.contract, event: "Update", logs: logs, sub: sub}, nil + return &ReplicaManagerHarnessSetConfirmationIterator{contract: _ReplicaManagerHarness.contract, event: "SetConfirmation", logs: logs, sub: sub}, nil } -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// WatchSetConfirmation is a free log subscription operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchSetConfirmation(opts *bind.WatchOpts, sink chan<- *ReplicaManagerHarnessSetConfirmation, remoteDomain []uint32, root [][32]byte) (event.Subscription, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var remoteDomainRule []interface{} + for _, remoteDomainItem := range remoteDomain { + remoteDomainRule = append(remoteDomainRule, remoteDomainItem) } var rootRule []interface{} for _, rootItem := range root { rootRule = append(rootRule, rootItem) } - logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _ReplicaManagerHarness.contract.WatchLogs(opts, "SetConfirmation", remoteDomainRule, rootRule) if err != nil { return nil, err } @@ -6420,8 +8778,8 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchUpdate(opts *b select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(ReplicaManagerHarnessUpdate) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "Update", log); err != nil { + event := new(ReplicaManagerHarnessSetConfirmation) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "SetConfirmation", log); err != nil { return err } event.Raw = log @@ -6442,12 +8800,12 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) WatchUpdate(opts *b }), nil } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// ParseSetConfirmation is a log parse operation binding the contract event 0x6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseUpdate(log types.Log) (*ReplicaManagerHarnessUpdate, error) { - event := new(ReplicaManagerHarnessUpdate) - if err := _ReplicaManagerHarness.contract.UnpackLog(event, "Update", log); err != nil { +// Solidity: event SetConfirmation(uint32 indexed remoteDomain, bytes32 indexed root, uint256 previousConfirmAt, uint256 newConfirmAt) +func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseSetConfirmation(log types.Log) (*ReplicaManagerHarnessSetConfirmation, error) { + event := new(ReplicaManagerHarnessSetConfirmation) + if err := _ReplicaManagerHarness.contract.UnpackLog(event, "SetConfirmation", log); err != nil { return nil, err } event.Raw = log @@ -6457,7 +8815,7 @@ func (_ReplicaManagerHarness *ReplicaManagerHarnessFilterer) ParseUpdate(log typ // StringsMetaData contains all meta data concerning the Strings contract. var StringsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e4a6b55ccddf986f92f5cfb09714263d2a6202b4b4f72d27ca49ee6f67e97d2f64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122028d30e262de413764f9374c0c5050a8b900adbe653e2b67fb50650448394b15c64736f6c634300080d0033", } // StringsABI is the input ABI used to generate the binding from. @@ -6627,308 +8985,125 @@ func (_Strings *StringsTransactorRaw) Transact(opts *bind.TransactOpts, method s return _Strings.Contract.contract.Transact(opts, method, params...) } -// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. -var SystemMessageMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220aca15275cad43ec21bf17eec94285c35a7f23050128748b1fd7887bd7c10347b64736f6c634300080d0033", -} - -// SystemMessageABI is the input ABI used to generate the binding from. -// Deprecated: Use SystemMessageMetaData.ABI instead. -var SystemMessageABI = SystemMessageMetaData.ABI - -// SystemMessageBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use SystemMessageMetaData.Bin instead. -var SystemMessageBin = SystemMessageMetaData.Bin - -// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. -func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { - parsed, err := SystemMessageMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil -} - -// SystemMessage is an auto generated Go binding around an Ethereum contract. -type SystemMessage struct { - SystemMessageCaller // Read-only binding to the contract - SystemMessageTransactor // Write-only binding to the contract - SystemMessageFilterer // Log filterer for contract events -} - -// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. -type SystemMessageCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type SystemMessageTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type SystemMessageFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// SystemMessageSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type SystemMessageSession struct { - Contract *SystemMessage // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type SystemMessageCallerSession struct { - Contract *SystemMessageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type SystemMessageTransactorSession struct { - Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. -type SystemMessageRaw struct { - Contract *SystemMessage // Generic contract binding to access the raw methods on -} - -// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type SystemMessageCallerRaw struct { - Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on -} - -// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type SystemMessageTransactorRaw struct { - Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { - contract, err := bindSystemMessage(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil -} - -// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { - contract, err := bindSystemMessage(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &SystemMessageCaller{contract: contract}, nil -} - -// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { - contract, err := bindSystemMessage(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &SystemMessageTransactor{contract: contract}, nil -} - -// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { - contract, err := bindSystemMessage(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &SystemMessageFilterer{contract: contract}, nil -} - -// bindSystemMessage binds a generic wrapper to an already deployed contract. -func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transact(opts, method, params...) -} - -// TipsMetaData contains all meta data concerning the Tips contract. -var TipsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ac88c3547b033099a64782d3089407652a47a25711fa74f8cc63c3f2c89e257764736f6c634300080d0033", -} - -// TipsABI is the input ABI used to generate the binding from. -// Deprecated: Use TipsMetaData.ABI instead. -var TipsABI = TipsMetaData.ABI - -// TipsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TipsMetaData.Bin instead. -var TipsBin = TipsMetaData.Bin - -// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. -func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { - parsed, err := TipsMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } - - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil +// SystemContractMetaData contains all meta data concerning the SystemContract contract. +var SystemContractMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8d3638f4": "localDomain()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "b7bc563e": "setSystemMessenger(address)", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + }, } -// Tips is an auto generated Go binding around an Ethereum contract. -type Tips struct { - TipsCaller // Read-only binding to the contract - TipsTransactor // Write-only binding to the contract - TipsFilterer // Log filterer for contract events +// SystemContractABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemContractMetaData.ABI instead. +var SystemContractABI = SystemContractMetaData.ABI + +// Deprecated: Use SystemContractMetaData.Sigs instead. +// SystemContractFuncSigs maps the 4-byte function signature to its string representation. +var SystemContractFuncSigs = SystemContractMetaData.Sigs + +// SystemContract is an auto generated Go binding around an Ethereum contract. +type SystemContract struct { + SystemContractCaller // Read-only binding to the contract + SystemContractTransactor // Write-only binding to the contract + SystemContractFilterer // Log filterer for contract events } -// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TipsCaller struct { +// SystemContractCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemContractCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TipsTransactor struct { +// SystemContractTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemContractTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TipsFilterer struct { +// SystemContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemContractFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsSession is an auto generated Go binding around an Ethereum contract, +// SystemContractSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TipsSession struct { - Contract *Tips // Generic contract binding to set the session for +type SystemContractSession struct { + Contract *SystemContract // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TipsCallerSession struct { - Contract *TipsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemContractCallerSession struct { + Contract *SystemContractCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TipsTransactorSession struct { - Contract *TipsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemContractTransactorSession struct { + Contract *SystemContractTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TipsRaw struct { - Contract *Tips // Generic contract binding to access the raw methods on +// SystemContractRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemContractRaw struct { + Contract *SystemContract // Generic contract binding to access the raw methods on } -// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TipsCallerRaw struct { - Contract *TipsCaller // Generic read-only contract binding to access the raw methods on +// SystemContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemContractCallerRaw struct { + Contract *SystemContractCaller // Generic read-only contract binding to access the raw methods on } -// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TipsTransactorRaw struct { - Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on +// SystemContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemContractTransactorRaw struct { + Contract *SystemContractTransactor // Generic write-only contract binding to access the raw methods on } -// NewTips creates a new instance of Tips, bound to a specific deployed contract. -func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { - contract, err := bindTips(address, backend, backend, backend) +// NewSystemContract creates a new instance of SystemContract, bound to a specific deployed contract. +func NewSystemContract(address common.Address, backend bind.ContractBackend) (*SystemContract, error) { + contract, err := bindSystemContract(address, backend, backend, backend) if err != nil { return nil, err } - return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil + return &SystemContract{SystemContractCaller: SystemContractCaller{contract: contract}, SystemContractTransactor: SystemContractTransactor{contract: contract}, SystemContractFilterer: SystemContractFilterer{contract: contract}}, nil } -// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. -func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { - contract, err := bindTips(address, caller, nil, nil) +// NewSystemContractCaller creates a new read-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractCaller(address common.Address, caller bind.ContractCaller) (*SystemContractCaller, error) { + contract, err := bindSystemContract(address, caller, nil, nil) if err != nil { return nil, err } - return &TipsCaller{contract: contract}, nil + return &SystemContractCaller{contract: contract}, nil } -// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. -func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { - contract, err := bindTips(address, nil, transactor, nil) +// NewSystemContractTransactor creates a new write-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemContractTransactor, error) { + contract, err := bindSystemContract(address, nil, transactor, nil) if err != nil { return nil, err } - return &TipsTransactor{contract: contract}, nil + return &SystemContractTransactor{contract: contract}, nil } -// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. -func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { - contract, err := bindTips(address, nil, nil, filterer) +// NewSystemContractFilterer creates a new log filterer instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemContractFilterer, error) { + contract, err := bindSystemContract(address, nil, nil, filterer) if err != nil { return nil, err } - return &TipsFilterer{contract: contract}, nil + return &SystemContractFilterer{contract: contract}, nil } -// bindTips binds a generic wrapper to an already deployed contract. -func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TipsABI)) +// bindSystemContract binds a generic wrapper to an already deployed contract. +func bindSystemContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemContractABI)) if err != nil { return nil, err } @@ -6939,237 +9114,500 @@ func bindTips(address common.Address, caller bind.ContractCaller, transactor bin // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.SystemContractCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transfer(opts) +func (_SystemContract *SystemContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.contract.Transfer(opts) +func (_SystemContract *SystemContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transact(opts, method, params...) } -// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. -var TypeCastsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206043199bfcbf1d096483744e4852fb3ab18a8af10a931440cec231cd1ffb96d964736f6c634300080d0033", +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// TypeCastsABI is the input ABI used to generate the binding from. -// Deprecated: Use TypeCastsMetaData.ABI instead. -var TypeCastsABI = TypeCastsMetaData.ABI +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} -// TypeCastsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypeCastsMetaData.Bin instead. -var TypeCastsBin = TypeCastsMetaData.Bin +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCallerSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "owner") -// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. -func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { - parsed, err := TypeCastsMetaData.GetAbi() if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + return *new(common.Address), err } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCallerSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "systemMessenger") + if err != nil { - return common.Address{}, nil, nil, err + return *new(common.Address), err } - return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// TypeCasts is an auto generated Go binding around an Ethereum contract. -type TypeCasts struct { - TypeCastsCaller // Read-only binding to the contract - TypeCastsTransactor // Write-only binding to the contract - TypeCastsFilterer // Log filterer for contract events +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypeCastsCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCallerSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypeCastsTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "renounceOwnership") } -// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypeCastsFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) } -// TypeCastsSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type TypeCastsSession struct { - Contract *TypeCasts // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "setSystemMessenger", _systemMessenger) } -// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type TypeCastsCallerSession struct { - Contract *TypeCastsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) +} + +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// SystemContractInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the SystemContract contract. +type SystemContractInitializedIterator struct { + Event *SystemContractInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type TypeCastsTransactorSession struct { - Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractInitializedIterator) Error() error { + return it.fail } -// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypeCastsRaw struct { - Contract *TypeCasts // Generic contract binding to access the raw methods on +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypeCastsCallerRaw struct { - Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on +// SystemContractInitialized represents a Initialized event raised by the SystemContract contract. +type SystemContractInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypeCastsTransactorRaw struct { - Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on -} +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) FilterInitialized(opts *bind.FilterOpts) (*SystemContractInitializedIterator, error) { -// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { - contract, err := bindTypeCasts(address, backend, backend, backend) + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + return &SystemContractInitializedIterator{contract: _SystemContract.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { - contract, err := bindTypeCasts(address, caller, nil, nil) +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *SystemContractInitialized) (event.Subscription, error) { + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypeCastsCaller{contract: contract}, nil + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { - contract, err := bindTypeCasts(address, nil, transactor, nil) - if err != nil { +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) ParseInitialized(log types.Log) (*SystemContractInitialized, error) { + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } - return &TypeCastsTransactor{contract: contract}, nil + event.Raw = log + return event, nil } -// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { - contract, err := bindTypeCasts(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &TypeCastsFilterer{contract: contract}, nil +// SystemContractOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the SystemContract contract. +type SystemContractOwnershipTransferredIterator struct { + Event *SystemContractOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// bindTypeCasts binds a generic wrapper to an already deployed contract. -func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) - if err != nil { - return nil, err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractOwnershipTransferredIterator) Error() error { + return it.fail } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.contract.Call(opts, result, method, params...) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transfer(opts) +// SystemContractOwnershipTransferred represents a OwnershipTransferred event raised by the SystemContract contract. +type SystemContractOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transact(opts, method, params...) +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*SystemContractOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &SystemContractOwnershipTransferredIterator{contract: _SystemContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. -var TypedMemViewMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "f26be3fc": "NULL()", - }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122076cea108b33e9e77fb1148c260dc13777ff564aa7a14f6f38bd36ab93a714f3564736f6c634300080d0033", +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *SystemContractOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TypedMemViewABI is the input ABI used to generate the binding from. -// Deprecated: Use TypedMemViewMetaData.ABI instead. -var TypedMemViewABI = TypedMemViewMetaData.ABI +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) ParseOwnershipTransferred(log types.Log) (*SystemContractOwnershipTransferred, error) { + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} -// Deprecated: Use TypedMemViewMetaData.Sigs instead. -// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. -var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs +// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. +var SystemMessageMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220822290f2e93bd6009ca8d8a7cb4a4f5a771aa48a155e5faddacc79fb2ee05ba864736f6c634300080d0033", +} -// TypedMemViewBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypedMemViewMetaData.Bin instead. -var TypedMemViewBin = TypedMemViewMetaData.Bin +// SystemMessageABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemMessageMetaData.ABI instead. +var SystemMessageABI = SystemMessageMetaData.ABI -// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. -func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { - parsed, err := TypedMemViewMetaData.GetAbi() +// SystemMessageBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SystemMessageMetaData.Bin instead. +var SystemMessageBin = SystemMessageMetaData.Bin + +// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. +func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { + parsed, err := SystemMessageMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -7177,111 +9615,111 @@ func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) ( return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// TypedMemView is an auto generated Go binding around an Ethereum contract. -type TypedMemView struct { - TypedMemViewCaller // Read-only binding to the contract - TypedMemViewTransactor // Write-only binding to the contract - TypedMemViewFilterer // Log filterer for contract events +// SystemMessage is an auto generated Go binding around an Ethereum contract. +type SystemMessage struct { + SystemMessageCaller // Read-only binding to the contract + SystemMessageTransactor // Write-only binding to the contract + SystemMessageFilterer // Log filterer for contract events } -// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypedMemViewCaller struct { +// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemMessageCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypedMemViewTransactor struct { +// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemMessageTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypedMemViewFilterer struct { +// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemMessageFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// SystemMessageSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TypedMemViewSession struct { - Contract *TypedMemView // Generic contract binding to set the session for +type SystemMessageSession struct { + Contract *SystemMessage // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TypedMemViewCallerSession struct { - Contract *TypedMemViewCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemMessageCallerSession struct { + Contract *SystemMessageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TypedMemViewTransactorSession struct { - Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemMessageTransactorSession struct { + Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypedMemViewRaw struct { - Contract *TypedMemView // Generic contract binding to access the raw methods on +// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemMessageRaw struct { + Contract *SystemMessage // Generic contract binding to access the raw methods on } -// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypedMemViewCallerRaw struct { - Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on +// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemMessageCallerRaw struct { + Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on } -// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypedMemViewTransactorRaw struct { - Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on +// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemMessageTransactorRaw struct { + Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on } -// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { - contract, err := bindTypedMemView(address, backend, backend, backend) +// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { + contract, err := bindSystemMessage(address, backend, backend, backend) if err != nil { return nil, err } - return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { - contract, err := bindTypedMemView(address, caller, nil, nil) +// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { + contract, err := bindSystemMessage(address, caller, nil, nil) if err != nil { return nil, err } - return &TypedMemViewCaller{contract: contract}, nil + return &SystemMessageCaller{contract: contract}, nil } -// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { - contract, err := bindTypedMemView(address, nil, transactor, nil) +// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { + contract, err := bindSystemMessage(address, nil, transactor, nil) if err != nil { return nil, err } - return &TypedMemViewTransactor{contract: contract}, nil + return &SystemMessageTransactor{contract: contract}, nil } -// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { - contract, err := bindTypedMemView(address, nil, nil, filterer) +// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { + contract, err := bindSystemMessage(address, nil, nil, filterer) if err != nil { return nil, err } - return &TypedMemViewFilterer{contract: contract}, nil + return &SystemMessageFilterer{contract: contract}, nil } -// bindTypedMemView binds a generic wrapper to an already deployed contract. -func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) +// bindSystemMessage binds a generic wrapper to an already deployed contract. +func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) if err != nil { return nil, err } @@ -7292,191 +9730,169 @@ func bindTypedMemView(address common.Address, caller bind.ContractCaller, transa // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) +func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transfer(opts) +func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transact(opts, method, params...) -} - -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { - var out []interface{} - err := _TypedMemView.contract.Call(opts, &out, "NULL") - - if err != nil { - return *new([29]byte), err - } - - out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - - return out0, err - +func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transact(opts, method, params...) } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) +// TipsMetaData contains all meta data concerning the Tips contract. +var TipsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220043b252cc500c302598c55278e0c81c985b31df4b734c03e0d334d5b30f9e53964736f6c634300080d0033", } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) -} +// TipsABI is the input ABI used to generate the binding from. +// Deprecated: Use TipsMetaData.ABI instead. +var TipsABI = TipsMetaData.ABI -// UpdaterStorageMetaData contains all meta data concerning the UpdaterStorage contract. -var UpdaterStorageMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "8d3638f4": "localDomain()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "b7bc563e": "setSystemMessenger(address)", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "df034cd0": "updater()", - }, -} +// TipsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TipsMetaData.Bin instead. +var TipsBin = TipsMetaData.Bin -// UpdaterStorageABI is the input ABI used to generate the binding from. -// Deprecated: Use UpdaterStorageMetaData.ABI instead. -var UpdaterStorageABI = UpdaterStorageMetaData.ABI +// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. +func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { + parsed, err := TipsMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } -// Deprecated: Use UpdaterStorageMetaData.Sigs instead. -// UpdaterStorageFuncSigs maps the 4-byte function signature to its string representation. -var UpdaterStorageFuncSigs = UpdaterStorageMetaData.Sigs + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil +} -// UpdaterStorage is an auto generated Go binding around an Ethereum contract. -type UpdaterStorage struct { - UpdaterStorageCaller // Read-only binding to the contract - UpdaterStorageTransactor // Write-only binding to the contract - UpdaterStorageFilterer // Log filterer for contract events +// Tips is an auto generated Go binding around an Ethereum contract. +type Tips struct { + TipsCaller // Read-only binding to the contract + TipsTransactor // Write-only binding to the contract + TipsFilterer // Log filterer for contract events } -// UpdaterStorageCaller is an auto generated read-only Go binding around an Ethereum contract. -type UpdaterStorageCaller struct { +// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TipsCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactor struct { +// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TipsTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UpdaterStorageFilterer struct { +// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TipsFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageSession is an auto generated Go binding around an Ethereum contract, +// TipsSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type UpdaterStorageSession struct { - Contract *UpdaterStorage // Generic contract binding to set the session for +type TipsSession struct { + Contract *Tips // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type UpdaterStorageCallerSession struct { - Contract *UpdaterStorageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type TipsCallerSession struct { + Contract *TipsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// UpdaterStorageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type UpdaterStorageTransactorSession struct { - Contract *UpdaterStorageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type TipsTransactorSession struct { + Contract *TipsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageRaw is an auto generated low-level Go binding around an Ethereum contract. -type UpdaterStorageRaw struct { - Contract *UpdaterStorage // Generic contract binding to access the raw methods on +// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TipsRaw struct { + Contract *Tips // Generic contract binding to access the raw methods on } -// UpdaterStorageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UpdaterStorageCallerRaw struct { - Contract *UpdaterStorageCaller // Generic read-only contract binding to access the raw methods on +// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TipsCallerRaw struct { + Contract *TipsCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactorRaw struct { - Contract *UpdaterStorageTransactor // Generic write-only contract binding to access the raw methods on +// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TipsTransactorRaw struct { + Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on } -// NewUpdaterStorage creates a new instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorage(address common.Address, backend bind.ContractBackend) (*UpdaterStorage, error) { - contract, err := bindUpdaterStorage(address, backend, backend, backend) +// NewTips creates a new instance of Tips, bound to a specific deployed contract. +func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { + contract, err := bindTips(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorage{UpdaterStorageCaller: UpdaterStorageCaller{contract: contract}, UpdaterStorageTransactor: UpdaterStorageTransactor{contract: contract}, UpdaterStorageFilterer: UpdaterStorageFilterer{contract: contract}}, nil + return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil } -// NewUpdaterStorageCaller creates a new read-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageCaller(address common.Address, caller bind.ContractCaller) (*UpdaterStorageCaller, error) { - contract, err := bindUpdaterStorage(address, caller, nil, nil) +// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. +func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { + contract, err := bindTips(address, caller, nil, nil) if err != nil { return nil, err } - return &UpdaterStorageCaller{contract: contract}, nil + return &TipsCaller{contract: contract}, nil } -// NewUpdaterStorageTransactor creates a new write-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageTransactor(address common.Address, transactor bind.ContractTransactor) (*UpdaterStorageTransactor, error) { - contract, err := bindUpdaterStorage(address, nil, transactor, nil) +// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. +func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { + contract, err := bindTips(address, nil, transactor, nil) if err != nil { return nil, err } - return &UpdaterStorageTransactor{contract: contract}, nil + return &TipsTransactor{contract: contract}, nil } -// NewUpdaterStorageFilterer creates a new log filterer instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageFilterer(address common.Address, filterer bind.ContractFilterer) (*UpdaterStorageFilterer, error) { - contract, err := bindUpdaterStorage(address, nil, nil, filterer) +// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. +func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { + contract, err := bindTips(address, nil, nil, filterer) if err != nil { return nil, err } - return &UpdaterStorageFilterer{contract: contract}, nil + return &TipsFilterer{contract: contract}, nil } -// bindUpdaterStorage binds a generic wrapper to an already deployed contract. -func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(UpdaterStorageABI)) +// bindTips binds a generic wrapper to an already deployed contract. +func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TipsABI)) if err != nil { return nil, err } @@ -7487,810 +9903,422 @@ func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.UpdaterStorageCaller.contract.Call(opts, result, method, params...) +func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transfer(opts) +func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transact(opts, method, params...) +func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.contract.Call(opts, result, method, params...) +func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transfer(opts) +func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transact(opts, method, params...) -} - -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "localDomain") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - +func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.contract.Transact(opts, method, params...) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) +// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. +var TypeCastsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122040cbb533e9c4c6d2931030d47b68281ae91292e5e46b5c67e7c22448cfa8a15b64736f6c634300080d0033", } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCallerSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) -} +// TypeCastsABI is the input ABI used to generate the binding from. +// Deprecated: Use TypeCastsMetaData.ABI instead. +var TypeCastsABI = TypeCastsMetaData.ABI -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "owner") +// TypeCastsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypeCastsMetaData.Bin instead. +var TypeCastsBin = TypeCastsMetaData.Bin +// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. +func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { + parsed, err := TypeCastsMetaData.GetAbi() if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) -} - -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "systemMessenger") - - if err != nil { - return *new(common.Address), err + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) -} - -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. -// -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "updater") - + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) -} - -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) + return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "renounceOwnership") +// TypeCasts is an auto generated Go binding around an Ethereum contract. +type TypeCasts struct { + TypeCastsCaller // Read-only binding to the contract + TypeCastsTransactor // Write-only binding to the contract + TypeCastsFilterer // Log filterer for contract events } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) +// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypeCastsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) +// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypeCastsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypeCastsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// TypeCastsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypeCastsSession struct { + Contract *TypeCasts // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypeCastsCallerSession struct { + Contract *TypeCastsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "transferOwnership", newOwner) +// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypeCastsTransactorSession struct { + Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypeCastsRaw struct { + Contract *TypeCasts // Generic contract binding to access the raw methods on } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypeCastsCallerRaw struct { + Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the UpdaterStorage contract. -type UpdaterStorageInitializedIterator struct { - Event *UpdaterStorageInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypeCastsTransactorRaw struct { + Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() +// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { + contract, err := bindTypeCasts(address, backend, backend, backend) + if err != nil { + return nil, err } + return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageInitializedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// UpdaterStorageInitialized represents a Initialized event raised by the UpdaterStorage contract. -type UpdaterStorageInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { + contract, err := bindTypeCasts(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TypeCastsCaller{contract: contract}, nil } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterInitialized(opts *bind.FilterOpts) (*UpdaterStorageInitializedIterator, error) { - - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Initialized") +// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { + contract, err := bindTypeCasts(address, nil, transactor, nil) if err != nil { return nil, err } - return &UpdaterStorageInitializedIterator{contract: _UpdaterStorage.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &TypeCastsTransactor{contract: contract}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *UpdaterStorageInitialized) (event.Subscription, error) { - - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Initialized") +// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { + contract, err := bindTypeCasts(address, nil, nil, filterer) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypeCastsFilterer{contract: contract}, nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseInitialized(log types.Log) (*UpdaterStorageInitialized, error) { - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { +// bindTypeCasts binds a generic wrapper to an already deployed contract. +func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// UpdaterStorageNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdaterIterator struct { - Event *UpdaterStorageNewUpdater // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.contract.Call(opts, result, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageNewUpdaterIterator) Error() error { - return it.fail +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transfer(opts) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transact(opts, method, params...) } -// UpdaterStorageNewUpdater represents a NewUpdater event raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. +var TypedMemViewMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "f26be3fc": "NULL()", + }, + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220d1b03f95375db81eee8540bd8d7399c4e899bf2267084e590b64a7d348bf1fc164736f6c634300080d0033", } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*UpdaterStorageNewUpdaterIterator, error) { +// TypedMemViewABI is the input ABI used to generate the binding from. +// Deprecated: Use TypedMemViewMetaData.ABI instead. +var TypedMemViewABI = TypedMemViewMetaData.ABI - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "NewUpdater") - if err != nil { - return nil, err - } - return &UpdaterStorageNewUpdaterIterator{contract: _UpdaterStorage.contract, event: "NewUpdater", logs: logs, sub: sub}, nil -} +// Deprecated: Use TypedMemViewMetaData.Sigs instead. +// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. +var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *UpdaterStorageNewUpdater) (event.Subscription, error) { +// TypedMemViewBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypedMemViewMetaData.Bin instead. +var TypedMemViewBin = TypedMemViewMetaData.Bin - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "NewUpdater") +// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. +func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { + parsed, err := TypedMemViewMetaData.GetAbi() if err != nil { - return nil, err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseNewUpdater(log types.Log) (*UpdaterStorageNewUpdater, error) { - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// TypedMemView is an auto generated Go binding around an Ethereum contract. +type TypedMemView struct { + TypedMemViewCaller // Read-only binding to the contract + TypedMemViewTransactor // Write-only binding to the contract + TypedMemViewFilterer // Log filterer for contract events } -// UpdaterStorageOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferredIterator struct { - Event *UpdaterStorageOwnershipTransferred // Event containing the contract specifics and raw log +// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypedMemViewCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypedMemViewTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypedMemViewFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypedMemViewSession struct { + Contract *TypedMemView // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypedMemViewCallerSession struct { + Contract *TypedMemViewCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypedMemViewTransactorSession struct { + Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageOwnershipTransferredIterator) Error() error { - return it.fail +// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypedMemViewRaw struct { + Contract *TypedMemView // Generic contract binding to access the raw methods on } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil +// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypedMemViewCallerRaw struct { + Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageOwnershipTransferred represents a OwnershipTransferred event raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypedMemViewTransactorRaw struct { + Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UpdaterStorageOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) +// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { + contract, err := bindTypedMemView(address, backend, backend, backend) + if err != nil { + return nil, err } + return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil +} - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { + contract, err := bindTypedMemView(address, caller, nil, nil) if err != nil { return nil, err } - return &UpdaterStorageOwnershipTransferredIterator{contract: _UpdaterStorage.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &TypedMemViewCaller{contract: contract}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UpdaterStorageOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) +// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { + contract, err := bindTypedMemView(address, nil, transactor, nil) + if err != nil { + return nil, err } + return &TypedMemViewTransactor{contract: contract}, nil +} - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { + contract, err := bindTypedMemView(address, nil, nil, filterer) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypedMemViewFilterer{contract: contract}, nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseOwnershipTransferred(log types.Log) (*UpdaterStorageOwnershipTransferred, error) { - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// bindTypedMemView binds a generic wrapper to an already deployed contract. +func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// UpdaterStorageUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the UpdaterStorage contract. -type UpdaterStorageUpdateIterator struct { - Event *UpdaterStorageUpdate // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageUpdateIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageUpdateIterator) Error() error { - return it.fail +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.contract.Call(opts, result, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterStorageUpdateIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transfer(opts) } -// UpdaterStorageUpdate represents a Update event raised by the UpdaterStorage contract. -type UpdaterStorageUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transact(opts, method, params...) } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*UpdaterStorageUpdateIterator, error) { - - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { + var out []interface{} + err := _TypedMemView.contract.Call(opts, &out, "NULL") - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new([29]byte), err } - return &UpdaterStorageUpdateIterator{contract: _UpdaterStorage.contract, event: "Update", logs: logs, sub: sub}, nil -} -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. -// -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *UpdaterStorageUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { + out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } + return out0, err - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { - return err - } - event.Raw = log +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. +// +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseUpdate(log types.Log) (*UpdaterStorageUpdate, error) { - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } // Version0MetaData contains all meta data concerning the Version0 contract. @@ -8299,7 +10327,7 @@ var Version0MetaData = &bind.MetaData{ Sigs: map[string]string{ "ffa1ad74": "VERSION()", }, - Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220cec0a89c824cbd4e8679a25b3ced6112eef8940537a0653b72c152453d78715f64736f6c634300080d0033", + Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212203f903fa32b0f92d9ee170255579912ffb29b34f63cfdb4688f7e0005d29be1a464736f6c634300080d0033", } // Version0ABI is the input ABI used to generate the binding from. diff --git a/core/contracts/test/replicamanagerharness/replicamanagerharness.contractinfo.json b/core/contracts/test/replicamanagerharness/replicamanagerharness.contractinfo.json index 6fb9d768eb..0e7797f7ce 100644 --- a/core/contracts/test/replicamanagerharness/replicamanagerharness.contractinfo.json +++ b/core/contracts/test/replicamanagerharness/replicamanagerharness.contractinfo.json @@ -1 +1 @@ -{"solidity/ReplicaManagerHarness.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122045f0ae72f6972f055d340df15ade41248d41b45df67b4ec5832c90c32e45746a64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122045f0ae72f6972f055d340df15ade41248d41b45df67b4ec5832c90c32e45746a64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"53465:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;53465:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"53465:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220138db4ec2682473b246847e5221eda76b4e56ce3165ba51993f0e5496b7962e764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220138db4ec2682473b246847e5221eda76b4e56ce3165ba51993f0e5496b7962e764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"72965:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;72965:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"72965:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b064a8ed2d124863495c5c80afc0eefe0b268aac8d265ccaafc03ff490c5562164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b064a8ed2d124863495c5c80afc0eefe0b268aac8d265ccaafc03ff490c5562164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"76183:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;76183:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"76183:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:AuthManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"AuthManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122050e91500f11e5e06dfc508414913cc284ef67d1cc354481005cd9a7a3f59e8f864736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122050e91500f11e5e06dfc508414913cc284ef67d1cc354481005cd9a7a3f59e8f864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44399:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;44399:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"44399:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e05411f0755cdc8f7a04b0971fb0613ef48b966a9285302b46caef9815783aaa64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e05411f0755cdc8f7a04b0971fb0613ef48b966a9285302b46caef9815783aaa64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"39115:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;39115:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"39115:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:IMessageRecipient":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_origin","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint256","name":"_rootTimestamp","type":"uint256"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"handle","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_rootTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"handle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"IMessageRecipient\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"handle(uint32,uint32,bytes32,uint256,bytes)":"e4d16d62"}},"solidity/ReplicaManagerHarness.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/ReplicaManagerHarness.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220bd62337655b3df25b537ec57e5be20820b2373f6e1c8885a0c56291e1ece44eb64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220bd62337655b3df25b537ec57e5be20820b2373f6e1c8885a0c56291e1ece44eb64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"83496:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;83496:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"83496:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220cb513ea91c1b35d5b5bf161884a4dda855c268c4213aad201c86506ddfd78de764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220cb513ea91c1b35d5b5bf161884a4dda855c268c4213aad201c86506ddfd78de764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"34142:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;34142:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"34142:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManagerHarness.sol:ReplicaLib":{"code":"0x6098610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212207d4468c7eb796bb0cde4fd87167c7dffd8650a2327021912be04056d3f1f6ed964736f6c634300080d0033","runtime-code":"0x7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212207d4468c7eb796bb0cde4fd87167c7dffd8650a2327021912be04056d3f1f6ed964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80495:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;80495:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"80495:2999:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81564:70;;81631:1;81564:70;;;;;168:25:1;;;156:2;141:18;81564:70:0;;;;;;;81502:56;;81556:1;81502:56;","abiDefinition":[{"inputs":[],"name":"MESSAGE_STATUS_NONE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_STATUS_PROCESSED","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"MESSAGE_STATUS_NONE":{"details":"Should not be possible to have 0x0 or 0x1 as valid Merkle root, so it's safe to use those values as NONE/PROCESSED"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"MESSAGE_STATUS_NONE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MESSAGE_STATUS_PROCESSED\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"MESSAGE_STATUS_NONE\":{\"details\":\"Should not be possible to have 0x0 or 0x1 as valid Merkle root, so it's safe to use those values as NONE/PROCESSED\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ReplicaLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"MESSAGE_STATUS_NONE()":"b0075818","MESSAGE_STATUS_PROCESSED()":"643d8086"}},"solidity/ReplicaManagerHarness.sol:ReplicaManager":{"code":"0x60a06040523480156200001157600080fd5b5060405162002dbc38038062002dbc833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612d206200009c60003960008181610256015281816108470152610eb80152612d206000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c8063928bc4b2116100cd578063ccbdf9c911610081578063f2fde38b11610066578063f2fde38b1461038e578063f646a512146103a1578063ffa1ad74146103b457600080fd5b8063ccbdf9c91461034e578063df034cd01461036e57600080fd5b80639df7d36d116100b25780639df7d36d146102f2578063b65672d314610305578063b7bc563e1461033b57600080fd5b8063928bc4b2146102cc5780639d54f419146102df57600080fd5b8063715018a6116101245780638624c35c116101095780638624c35c1461023e5780638d3638f4146102515780638da5cb5b1461028d57600080fd5b8063715018a6146101f55780637dfdba28146101fd57600080fd5b806315a046aa146101565780634f63be3f1461017e578063634155141461019157806368705275146101e0575b600080fd5b610169610164366004612701565b6103ce565b60405190151581526020015b60405180910390f35b61016961018c366004612817565b61042b565b6101d261019f366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b604051908152602001610175565b6101f36101ee366004612817565b6105a5565b005b6101f361060c565b6101d261020b366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101f361024c3660046128d3565b610675565b6102787f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6101f36102da36600461290a565b6107ee565b6101f36102ed36600461293f565b610b8a565b6101f361030036600461295c565b610bfa565b61027861031336600461298f565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101f361034936600461293f565b610cee565b6066546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6101f361039c36600461293f565b610d9c565b6101f36103af36600461290a565b610e95565b6103bc600081565b60405160ff9091168152602001610175565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361040d576000915050610424565b61041d63ffffffff8516826129d9565b4210159150505b9392505050565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff16600281111561047a5761047a6129f1565b146104cc5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561052a5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016104c3565b60006105608387602080602002604051908101604052809291908260208002808284376000920191909152508991506110709050565b60008181526001840160205260409020549091501561059557600092835260029190910160205260409091205550600161059d565b600093505050505b949350505050565b6105b18484848461042b565b6105fd5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016104c3565b610606836107ee565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106735760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b565b60006106816001611116565b905080156106b657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6106bf8261126d565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107708360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc602052604090205580156107e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006107f9826112f2565b9050600061080c62ffffff198316611306565b9050600061081f62ffffff198316611346565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661087662ffffff198516611370565b63ffffffff16146108c95760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016104c3565b60006108da62ffffff198616611391565b60008181526002840160205260409020549091506108f7816113ee565b6109435760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016104c3565b61095c8461095662ffffff198816611402565b836103ce565b6109a85760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016104c3565b60c95460ff166001146109fd5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016104c3565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610a3a610a3762ffffff198816611423565b50565b6000828152600284016020526040812060019055610a65610a6062ffffff19881661145a565b61147b565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610a9362ffffff198a166114bd565b610aa262ffffff198b166114de565b600087815260018a016020526040902054610ad0610ac562ffffff198f166114ff565b62ffffff191661153e565b6040518663ffffffff1660e01b8152600401610af0959493929190612a8b565b600060405180830381600087803b158015610b0a57600080fd5b505af1158015610b1e573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bf15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b610a3781611591565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610ca49083908690869061161716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d555760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b73ffffffffffffffffffffffffffffffffffffffff8116610e8c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104c3565b610a378161162b565b6000610ea0826116a2565b9150506000610eb48262ffffff19166117c3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610f315760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016104c3565b6000610f4262ffffff1984166117d7565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020805492935091811690831611610fbd5760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016104c3565b6000610fce62ffffff1986166117eb565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171611053610ac58a62ffffff1916611800565b6040516110609190612acb565b60405180910390a4505050505050565b8260005b602081101561110e57600183821c16600085836020811061109757611097612ade565b60200201519050816001036110d7576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611104565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611074565b509392505050565b60008054610100900460ff16156111b3578160ff1660011480156111395750303b155b6111ab5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b506000919050565b60005460ff8084169116106112305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166112ea5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610bf1611833565b6000611300826105396118b8565b92915050565b60008161131b62ffffff1982166105396118dc565b5061133d8361132b8560016119dd565b6113368660026119dd565b6001611a0f565b91505b50919050565b60008161135c60015b62ffffff198316906118dc565b5061133d62ffffff19841660026004611a2e565b60008161137d600161134f565b5061133d62ffffff198416602a6004611a2e565b6000806113ac8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006113d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906113005750506001141590565b60008161140f600161134f565b5061133d62ffffff198416604e6004611a2e565b60008161143862ffffff1982166105396118dc565b5061133d836114488560026119dd565b6114538660036119dd565b6002611a0f565b600081611467600161134f565b5061133d62ffffff198416602e6020611a5e565b60007401000000000000000000000000000000000000000082016114b757505060665473ffffffffffffffffffffffffffffffffffffffff1690565b81611300565b6000816114ca600161134f565b5061133d62ffffff19841660266004611a2e565b6000816114eb600161134f565b5061133d62ffffff19841660066020611a5e565b60008161151462ffffff1982166105396118dc565b5061133d836115248560036119dd565b601886901c6bffffffffffffffffffffffff166003611a0f565b606060008061155b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506115808483602001611c1c565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806116af83826118b8565b905060286bffffffffffffffffffffffff601883901c16116117135760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016104c3565b61173c61172562ffffff198316611dc1565b611737610ac562ffffff198516611800565b611dd6565b915061177261175062ffffff1983166117c3565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6117be5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e2075706461746572000000000000000060448201526064016104c3565b915091565b600061130062ffffff198316826004611a2e565b600061130062ffffff198316600480611a2e565b600061130062ffffff19831660086020611a5e565b6000611300602861182381601886901c6bffffffffffffffffffffffff16612b0d565b62ffffff19851691906000611e4d565b600054610100900460ff166118b05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610673611ec7565b8151600090602084016118d364ffffffffff85168284611f4d565b95945050505050565b60006118e88383611f94565b6119d65760006119076118fb8560d81c90565b64ffffffffff16611fb7565b915050600061191c8464ffffffffff16611fb7565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016104c39190612acb565b5090919050565b600061042460028360048111156119f6576119f66129f1565b611a009190612b24565b62ffffff198516906002611a2e565b60006118d384611a1f8186612b0d565b62ffffff198816919085611e4d565b6000611a3b826020612b61565b611a46906008612b84565b60ff16611a54858585611a5e565b901c949350505050565b60008160ff16600003611a7357506000610424565b611a8b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aa660ff8416856129d9565b1115611b1e57611b05611ac78560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aed8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166120a1565b60405162461bcd60e51b81526004016104c39190612acb565b60208260ff161115611b985760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104c3565b600882026000611bb68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611c995760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016104c3565b611ca28361210f565b611d145760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016104c3565b6000611d2e8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611d588560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611d7d5760206060fd5b8285848460045afa50611db7611d938760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061130062ffffff19831682602881611e4d565b600080611de862ffffff198516611391565b9050611e41816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061059d818461214c565b600080611e688660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050611e8186612168565b84611e8c87846129d9565b611e9691906129d9565b1115611ea95762ffffff1991505061059d565b611eb385826129d9565b9050611db78364ffffffffff168286611f4d565b600054610100900460ff16611f445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b6106733361162b565b600080611f5a83856129d9565b9050604051811115611f6a575060005b80600003611f7f5762ffffff19915050610424565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16611fa88460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561202a576000611fd6826008612b84565b60ff1685901c9050611fe7816121b0565b61ffff16841793508160ff1660101461200257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611fbd565b50600f5b60ff8160ff16101561209b576000612047826008612b84565b60ff1685901c9050612058816121b0565b61ffff16831792508160ff1660001461207357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161202e565b50915091565b606060006120ae86611fb7565b91505060006120bc86611fb7565b91505060006120ca86611fb7565b91505060006120d886611fb7565b915050838383836040516020016120f29493929190612bad565b604051602081830303815290604052945050505050949350505050565b600061211b8260d81c90565b64ffffffffff1664ffffffffff0361213557506000919050565b600061214083612168565b60405110199392505050565b600080600061215b85856121e2565b9150915061110e81612250565b60006121828260181c6bffffffffffffffffffffffff1690565b61219a8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006121c260048360ff16901c61243c565b60ff1661ffff919091161760081b6121d98261243c565b60ff1617919050565b60008082516041036122185760208301516040840151606085015160001a61220c87828585612583565b94509450505050612249565b8251604003612241576020830151604084015161223686838361269b565b935093505050612249565b506000905060025b9250929050565b6000816004811115612264576122646129f1565b0361226c5750565b6001816004811115612280576122806129f1565b036122cd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104c3565b60028160048111156122e1576122e16129f1565b0361232e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104c3565b6003816004811115612342576123426129f1565b036123b55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b60048160048111156123c9576123c96129f1565b03610a375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b600060f08083179060ff821690036124575750603092915050565b8060ff1660f10361246b5750603192915050565b8060ff1660f20361247f5750603292915050565b8060ff1660f3036124935750603392915050565b8060ff1660f4036124a75750603492915050565b8060ff1660f5036124bb5750603592915050565b8060ff1660f6036124cf5750603692915050565b8060ff1660f7036124e35750603792915050565b8060ff1660f8036124f75750603892915050565b8060ff1660f90361250b5750603992915050565b8060ff1660fa0361251f5750606192915050565b8060ff1660fb036125335750606292915050565b8060ff1660fc036125475750606392915050565b8060ff1660fd0361255b5750606492915050565b8060ff1660fe0361256f5750606592915050565b8060ff1660ff036113405750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156125ba5750600090506003612692565b8460ff16601b141580156125d257508460ff16601c14155b156125e35750600090506004612692565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612637573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661268b57600060019250925050612692565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816126d160ff86901c601b6129d9565b90506126df87828885612583565b935093505050935093915050565b803563ffffffff8116811461126857600080fd5b60008060006060848603121561271657600080fd5b61271f846126ed565b925061272d602085016126ed565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261277d57600080fd5b813567ffffffffffffffff808211156127985761279861273d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156127de576127de61273d565b816040528381528660208588010111156127f757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561282e57600080fd5b612837856126ed565b9350602085013567ffffffffffffffff81111561285357600080fd5b61285f8782880161276c565b93505061044085018681111561287457600080fd5b9396929550505060409290920191903590565b6000806040838503121561289a57600080fd5b6128a3836126ed565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a3757600080fd5b600080604083850312156128e657600080fd5b6128ef836126ed565b915060208301356128ff816128b1565b809150509250929050565b60006020828403121561291c57600080fd5b813567ffffffffffffffff81111561293357600080fd5b61059d8482850161276c565b60006020828403121561295157600080fd5b8135610424816128b1565b60008060006060848603121561297157600080fd5b61297a846126ed565b95602085013595506040909401359392505050565b6000602082840312156129a157600080fd5b610424826126ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156129ec576129ec6129aa565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612a4657602081850181015186830182015201612a2a565b81811115612a58576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612ac060a0830184612a20565b979650505050505050565b6020815260006104246020830184612a20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612b1f57612b1f6129aa565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b5c57612b5c6129aa565b500290565b600060ff821660ff841680821015612b7b57612b7b6129aa565b90039392505050565b600060ff821660ff84168160ff0481118215151615612ba557612ba56129aa565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611db756fea26469706673582212200899b279b0d431134d4bcadf8747cd7499dbea379b7c3b1ddadf39f5a0f6c6ab64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106101515760003560e01c8063928bc4b2116100cd578063ccbdf9c911610081578063f2fde38b11610066578063f2fde38b1461038e578063f646a512146103a1578063ffa1ad74146103b457600080fd5b8063ccbdf9c91461034e578063df034cd01461036e57600080fd5b80639df7d36d116100b25780639df7d36d146102f2578063b65672d314610305578063b7bc563e1461033b57600080fd5b8063928bc4b2146102cc5780639d54f419146102df57600080fd5b8063715018a6116101245780638624c35c116101095780638624c35c1461023e5780638d3638f4146102515780638da5cb5b1461028d57600080fd5b8063715018a6146101f55780637dfdba28146101fd57600080fd5b806315a046aa146101565780634f63be3f1461017e578063634155141461019157806368705275146101e0575b600080fd5b610169610164366004612701565b6103ce565b60405190151581526020015b60405180910390f35b61016961018c366004612817565b61042b565b6101d261019f366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b604051908152602001610175565b6101f36101ee366004612817565b6105a5565b005b6101f361060c565b6101d261020b366004612887565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101f361024c3660046128d3565b610675565b6102787f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610175565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610175565b6101f36102da36600461290a565b6107ee565b6101f36102ed36600461293f565b610b8a565b6101f361030036600461295c565b610bfa565b61027861031336600461298f565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101f361034936600461293f565b610cee565b6066546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102a79073ffffffffffffffffffffffffffffffffffffffff1681565b6101f361039c36600461293f565b610d9c565b6101f36103af36600461290a565b610e95565b6103bc600081565b60405160ff9091168152602001610175565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361040d576000915050610424565b61041d63ffffffff8516826129d9565b4210159150505b9392505050565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff16600281111561047a5761047a6129f1565b146104cc5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561052a5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016104c3565b60006105608387602080602002604051908101604052809291908260208002808284376000920191909152508991506110709050565b60008181526001840160205260409020549091501561059557600092835260029190910160205260409091205550600161059d565b600093505050505b949350505050565b6105b18484848461042b565b6105fd5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016104c3565b610606836107ee565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106735760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b565b60006106816001611116565b905080156106b657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6106bf8261126d565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107708360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc602052604090205580156107e957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b60006107f9826112f2565b9050600061080c62ffffff198316611306565b9050600061081f62ffffff198316611346565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661087662ffffff198516611370565b63ffffffff16146108c95760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016104c3565b60006108da62ffffff198616611391565b60008181526002840160205260409020549091506108f7816113ee565b6109435760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016104c3565b61095c8461095662ffffff198816611402565b836103ce565b6109a85760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016104c3565b60c95460ff166001146109fd5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016104c3565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610a3a610a3762ffffff198816611423565b50565b6000828152600284016020526040812060019055610a65610a6062ffffff19881661145a565b61147b565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610a9362ffffff198a166114bd565b610aa262ffffff198b166114de565b600087815260018a016020526040902054610ad0610ac562ffffff198f166114ff565b62ffffff191661153e565b6040518663ffffffff1660e01b8152600401610af0959493929190612a8b565b600060405180830381600087803b158015610b0a57600080fd5b505af1158015610b1e573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bf15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b610a3781611591565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610ca49083908690869061161716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d555760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104c3565b73ffffffffffffffffffffffffffffffffffffffff8116610e8c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104c3565b610a378161162b565b6000610ea0826116a2565b9150506000610eb48262ffffff19166117c3565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610f315760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016104c3565b6000610f4262ffffff1984166117d7565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020805492935091811690831611610fbd5760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016104c3565b6000610fce62ffffff1986166117eb565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171611053610ac58a62ffffff1916611800565b6040516110609190612acb565b60405180910390a4505050505050565b8260005b602081101561110e57600183821c16600085836020811061109757611097612ade565b60200201519050816001036110d7576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611104565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611074565b509392505050565b60008054610100900460ff16156111b3578160ff1660011480156111395750303b155b6111ab5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b506000919050565b60005460ff8084169116106112305760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016104c3565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166112ea5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610bf1611833565b6000611300826105396118b8565b92915050565b60008161131b62ffffff1982166105396118dc565b5061133d8361132b8560016119dd565b6113368660026119dd565b6001611a0f565b91505b50919050565b60008161135c60015b62ffffff198316906118dc565b5061133d62ffffff19841660026004611a2e565b60008161137d600161134f565b5061133d62ffffff198416602a6004611a2e565b6000806113ac8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006113d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906113005750506001141590565b60008161140f600161134f565b5061133d62ffffff198416604e6004611a2e565b60008161143862ffffff1982166105396118dc565b5061133d836114488560026119dd565b6114538660036119dd565b6002611a0f565b600081611467600161134f565b5061133d62ffffff198416602e6020611a5e565b60007401000000000000000000000000000000000000000082016114b757505060665473ffffffffffffffffffffffffffffffffffffffff1690565b81611300565b6000816114ca600161134f565b5061133d62ffffff19841660266004611a2e565b6000816114eb600161134f565b5061133d62ffffff19841660066020611a5e565b60008161151462ffffff1982166105396118dc565b5061133d836115248560036119dd565b601886901c6bffffffffffffffffffffffff166003611a0f565b606060008061155b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506115808483602001611c1c565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806116af83826118b8565b905060286bffffffffffffffffffffffff601883901c16116117135760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016104c3565b61173c61172562ffffff198316611dc1565b611737610ac562ffffff198516611800565b611dd6565b915061177261175062ffffff1983166117c3565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6117be5760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e2075706461746572000000000000000060448201526064016104c3565b915091565b600061130062ffffff198316826004611a2e565b600061130062ffffff198316600480611a2e565b600061130062ffffff19831660086020611a5e565b6000611300602861182381601886901c6bffffffffffffffffffffffff16612b0d565b62ffffff19851691906000611e4d565b600054610100900460ff166118b05760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b610673611ec7565b8151600090602084016118d364ffffffffff85168284611f4d565b95945050505050565b60006118e88383611f94565b6119d65760006119076118fb8560d81c90565b64ffffffffff16611fb7565b915050600061191c8464ffffffffff16611fb7565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016104c39190612acb565b5090919050565b600061042460028360048111156119f6576119f66129f1565b611a009190612b24565b62ffffff198516906002611a2e565b60006118d384611a1f8186612b0d565b62ffffff198816919085611e4d565b6000611a3b826020612b61565b611a46906008612b84565b60ff16611a54858585611a5e565b901c949350505050565b60008160ff16600003611a7357506000610424565b611a8b8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aa660ff8416856129d9565b1115611b1e57611b05611ac78560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611aed8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166120a1565b60405162461bcd60e51b81526004016104c39190612acb565b60208260ff161115611b985760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016104c3565b600882026000611bb68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611c995760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016104c3565b611ca28361210f565b611d145760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016104c3565b6000611d2e8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611d588560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611d7d5760206060fd5b8285848460045afa50611db7611d938760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061130062ffffff19831682602881611e4d565b600080611de862ffffff198516611391565b9050611e41816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061059d818461214c565b600080611e688660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050611e8186612168565b84611e8c87846129d9565b611e9691906129d9565b1115611ea95762ffffff1991505061059d565b611eb385826129d9565b9050611db78364ffffffffff168286611f4d565b600054610100900460ff16611f445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016104c3565b6106733361162b565b600080611f5a83856129d9565b9050604051811115611f6a575060005b80600003611f7f5762ffffff19915050610424565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff16611fa88460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561202a576000611fd6826008612b84565b60ff1685901c9050611fe7816121b0565b61ffff16841793508160ff1660101461200257601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611fbd565b50600f5b60ff8160ff16101561209b576000612047826008612b84565b60ff1685901c9050612058816121b0565b61ffff16831792508160ff1660001461207357601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161202e565b50915091565b606060006120ae86611fb7565b91505060006120bc86611fb7565b91505060006120ca86611fb7565b91505060006120d886611fb7565b915050838383836040516020016120f29493929190612bad565b604051602081830303815290604052945050505050949350505050565b600061211b8260d81c90565b64ffffffffff1664ffffffffff0361213557506000919050565b600061214083612168565b60405110199392505050565b600080600061215b85856121e2565b9150915061110e81612250565b60006121828260181c6bffffffffffffffffffffffff1690565b61219a8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006121c260048360ff16901c61243c565b60ff1661ffff919091161760081b6121d98261243c565b60ff1617919050565b60008082516041036122185760208301516040840151606085015160001a61220c87828585612583565b94509450505050612249565b8251604003612241576020830151604084015161223686838361269b565b935093505050612249565b506000905060025b9250929050565b6000816004811115612264576122646129f1565b0361226c5750565b6001816004811115612280576122806129f1565b036122cd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104c3565b60028160048111156122e1576122e16129f1565b0361232e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104c3565b6003816004811115612342576123426129f1565b036123b55760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b60048160048111156123c9576123c96129f1565b03610a375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016104c3565b600060f08083179060ff821690036124575750603092915050565b8060ff1660f10361246b5750603192915050565b8060ff1660f20361247f5750603292915050565b8060ff1660f3036124935750603392915050565b8060ff1660f4036124a75750603492915050565b8060ff1660f5036124bb5750603592915050565b8060ff1660f6036124cf5750603692915050565b8060ff1660f7036124e35750603792915050565b8060ff1660f8036124f75750603892915050565b8060ff1660f90361250b5750603992915050565b8060ff1660fa0361251f5750606192915050565b8060ff1660fb036125335750606292915050565b8060ff1660fc036125475750606392915050565b8060ff1660fd0361255b5750606492915050565b8060ff1660fe0361256f5750606592915050565b8060ff1660ff036113405750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156125ba5750600090506003612692565b8460ff16601b141580156125d257508460ff16601c14155b156125e35750600090506004612692565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612637573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661268b57600060019250925050612692565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816126d160ff86901c601b6129d9565b90506126df87828885612583565b935093505050935093915050565b803563ffffffff8116811461126857600080fd5b60008060006060848603121561271657600080fd5b61271f846126ed565b925061272d602085016126ed565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261277d57600080fd5b813567ffffffffffffffff808211156127985761279861273d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156127de576127de61273d565b816040528381528660208588010111156127f757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561282e57600080fd5b612837856126ed565b9350602085013567ffffffffffffffff81111561285357600080fd5b61285f8782880161276c565b93505061044085018681111561287457600080fd5b9396929550505060409290920191903590565b6000806040838503121561289a57600080fd5b6128a3836126ed565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610a3757600080fd5b600080604083850312156128e657600080fd5b6128ef836126ed565b915060208301356128ff816128b1565b809150509250929050565b60006020828403121561291c57600080fd5b813567ffffffffffffffff81111561293357600080fd5b61059d8482850161276c565b60006020828403121561295157600080fd5b8135610424816128b1565b60008060006060848603121561297157600080fd5b61297a846126ed565b95602085013595506040909401359392505050565b6000602082840312156129a157600080fd5b610424826126ed565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082198211156129ec576129ec6129aa565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612a4657602081850181015186830182015201612a2a565b81811115612a58576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612ac060a0830184612a20565b979650505050505050565b6020815260006104246020830184612a20565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612b1f57612b1f6129aa565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b5c57612b5c6129aa565b500290565b600060ff821660ff841680821015612b7b57612b7b6129aa565b90039392505050565b600060ff821660ff84168160ff0481118215151615612ba557612ba56129aa565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611db756fea26469706673582212200899b279b0d431134d4bcadf8747cd7499dbea379b7c3b1ddadf39f5a0f6c6ab64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"98950:12604:0:-:0;;;100766:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71526:26;;;;98950:12604;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;98950:12604:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"98950:12604:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107582:361;;;;;;:::i;:::-;;:::i;:::-;;;676:14:1;;669:22;651:41;;639:2;624:18;107582:361:0;;;;;;;;108605:1028;;;;;;:::i;:::-;;:::i;102029:230::-;;;;;;:::i;:::-;102196:29;;;;;102154:7;102196:29;;;:14;:29;;;;;;;;;102184:42;;:11;:42;;;;;:68;;;:56;;;;:68;;;;;102029:230;;;;2691:25:1;;;2679:2;2664:18;102029:230:0;2545:177:1;103931:271:0;;;;;;:::i;:::-;;:::i;:::-;;72877:84;;;:::i;101809:214::-;;;;;;:::i;:::-;101969:29;;;;;101927:7;101969:29;;;:14;:29;;;;;;;;;101957:42;;:11;:42;;;;;:59;;;:52;;;;:59;;;;;101809:214;101334:255;;;;;;:::i;:::-;;:::i;70324:35::-;;;;;;;;3566:10:1;3554:23;;;3536:42;;3524:2;3509:18;70324:35:0;3392:192:1;68421:85:0;68493:6;;;;68421:85;;;3765:42:1;3753:55;;;3735:74;;3723:2;3708:18;68421:85:0;3589:226:1;104640:1415:0;;;;;;:::i;:::-;;:::i;106346:95::-;;;;;;:::i;:::-;;:::i;106792:423::-;;;;;;:::i;:::-;;:::i;101650:153::-;;;;;;:::i;:::-;101760:29;;;;101723:6;101760:29;;;:14;:29;;;;;;;;;101748:42;;:11;:42;;;;;:48;;;101650:153;72075:133;;;;;;:::i;:::-;;:::i;70479:39::-;;;;;;;;;70450:22;;;;;;;;;69303:198;;;;;;:::i;:::-;;:::i;102749:731::-;;;;;;:::i;:::-;;:::i;80457:33::-;;80489:1;80457:33;;;;;5612:4:1;5600:17;;;5582:36;;5570:2;5555:18;80457:33:0;5440:184:1;107582:361:0;107765:29;;;107721:4;107765:29;;;:14;:29;;;;;;;;;107753:42;;:11;:42;;;;;:59;;;:52;;:59;;;;;;107826:10;;;107822:53;;107859:5;107852:12;;;;;107822:53;107910:26;;;;:5;:26;:::i;:::-;107891:15;:45;;107884:52;;;107582:361;;;;;;:::o;108605:1028::-;108796:19;;;;;;;;;;108874:29;;;108764:4;108874:29;;;:14;:29;;;;;;;108862:42;;:11;:42;;;;;;108981:31;108963:14;;;;;;;:49;;;;;;;;:::i;:::-;;108955:80;;;;-1:-1:-1;;;108955:80:0;;6342:2:1;108955:80:0;;;6324:21:1;6381:2;6361:18;;;6354:30;6420:20;6400:18;;;6393:48;6458:18;;108955:80:0;;;;;;;;;81556:1;109130:28;;;:21;;;:28;;;;;;:62;109109:128;;;;-1:-1:-1;;;109109:128:0;;6689:2:1;109109:128:0;;;6671:21:1;6728:2;6708:18;;;6701:30;6767:21;6747:18;;;6740:49;6806:18;;109109:128:0;6487:343:1;109109:128:0;109305:23;109331:43;109352:5;109359:6;109331:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109367:6:0;;-1:-1:-1;109331:20:0;;-1:-1:-1;109331:43:0:i;:::-;109466:34;;;;:17;;;:34;;;;;;109305:69;;-1:-1:-1;109466:39:0;109462:143;;83129:35;;;;:21;;;;;:35;;;;;;:45;-1:-1:-1;109590:4:0;109583:11;;109462:143;109621:5;109614:12;;;;;108605:1028;;;;;;;:::o;103931:271::-;104111:46;104117:13;104132:8;104142:6;104150;104111:5;:46::i;:::-;104103:65;;;;-1:-1:-1;;;104103:65:0;;7037:2:1;104103:65:0;;;7019:21:1;7076:1;7056:18;;;7049:29;7114:8;7094:18;;;7087:36;7140:18;;104103:65:0;6835:329:1;104103:65:0;104178:17;104186:8;104178:7;:17::i;:::-;103931:271;;;;:::o;72877:84::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;72877:84::o;101334:255::-;61317:19;61339:25;61362:1;61339:22;:25::i;:::-;61317:47;;61378:14;61374:65;;;61408:13;:20;;;;;;;;61374:65;101423:34:::1;101448:8;101423:24;:34::i;:::-;101500:7;:11:::0;;;::::1;101510:1;101500:11;::::0;;101553:29:::1;101568:13:::0;109922:12;;109937:1;109922:16;109756:20;109958:25;;;:11;:25;;;;;82601:36;;;;;;;82647:37;;;;;;;;;;;110021:12;:27;;;110036:12;109692:363;-1:-1:-1;109692:363:0;101553:29:::1;101521;::::0;::::1;;::::0;;;:14:::1;:29;::::0;;;;:61;61459:99;;;;61509:5;61493:21;;;;;;61533:14;;-1:-1:-1;5582:36:1;;61533:14:0;;5570:2:1;5555:18;61533:14:0;;;;;;;61459:99;61307:257;101334:255;;:::o;104640:1415::-;104697:10;104710:22;:8;:20;:22::i;:::-;104697:35;-1:-1:-1;104742:15:0;104760:11;-1:-1:-1;;104760:9:0;;;:11::i;:::-;104742:29;-1:-1:-1;104781:20:0;104804:16;-1:-1:-1;;104804:14:0;;;:16::i;:::-;104879:29;;;;104830:34;104879:29;;;:14;:29;;;;;;;;;104867:42;;:11;:42;;;;;104781:39;;-1:-1:-1;105004:11:0;104979:36;:21;-1:-1:-1;;104979:19:0;;;:21::i;:::-;:36;;;104971:61;;;;-1:-1:-1;;;104971:61:0;;7931:2:1;104971:61:0;;;7913:21:1;7970:2;7950:18;;;7943:30;8009:14;7989:18;;;7982:42;8041:18;;104971:61:0;7729:336:1;104971:61:0;105084:20;105107:11;-1:-1:-1;;105107:9:0;;;:11::i;:::-;105128:13;105144:35;;;:21;;;:35;;;;;;105084:34;;-1:-1:-1;105197:33:0;105144:35;105197:26;:33::i;:::-;105189:66;;;;-1:-1:-1;;;105189:66:0;;8272:2:1;105189:66:0;;;8254:21:1;8311:2;8291:18;;;8284:30;8350:22;8330:18;;;8323:50;8390:18;;105189:66:0;8070:344:1;105189:66:0;105286:65;105301:13;105316:27;-1:-1:-1;;105316:25:0;;;:27::i;:::-;105345:5;105286:14;:65::i;:::-;105265:130;;;;-1:-1:-1;;;105265:130:0;;8621:2:1;105265:130:0;;;8603:21:1;8660:2;8640:18;;;8633:30;8699:20;8679:18;;;8672:48;8737:18;;105265:130:0;8419:342:1;105265:130:0;105448:7;;;;;:12;105440:35;;;;-1:-1:-1;;;105440:35:0;;8968:2:1;105440:35:0;;;8950:21:1;9007:2;8987:18;;;8980:30;9046:12;9026:18;;;9019:40;9076:18;;105440:35:0;8766:334:1;105440:35:0;105485:7;:11;;;;;;105506:21;105517:9;-1:-1:-1;;105517:7:0;;;:9::i;:::-;106346:95;;105506:21;83129:35;;;;:21;;;:35;;;;;81631:1;83129:45;;105688:43;105711:19;-1:-1:-1;;105711:17:0;;;:19::i;:::-;105688:22;:43::i;:::-;105668:63;-1:-1:-1;105741:35:0;;;;105790:13;105817:15;-1:-1:-1;;105817:13:0;;;:15::i;:::-;105846:16;-1:-1:-1;;105846:14:0;;;:16::i;:::-;105876:24;;;;:17;;;:24;;;;;;105914:17;:9;-1:-1:-1;;105914:7:0;;;:9::i;:::-;-1:-1:-1;;105914:15:0;;:17::i;:::-;105741:200;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;105956:36:0;;105979:12;;-1:-1:-1;105956:36:0;;;;-1:-1:-1;105956:36:0;;;;;-1:-1:-1;;106037:7:0;:11;;;;106047:1;106037:11;;;-1:-1:-1;;;;;;104640:1415:0:o;106346:95::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;106413:21:::1;106425:8;106413:11;:21::i;106792:423::-:0;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;106982:29:::1;::::0;;::::1;106933:34;106982:29:::0;;;:14:::1;:29;::::0;;;;;;;;106970:42;;:11:::1;:42:::0;;;;;107051:24;;;:17:::1;::::0;::::1;:24:::0;;;;;;;106970:42;;107085:39:::1;::::0;106970:42;;107069:5;;107113:10;;107085:20:::1;:39;:::i;:::-;107139:69;::::0;;10366:25:1;;;10422:2;10407:18;;10400:34;;;107170:5:0;;107139:69:::1;::::0;::::1;::::0;::::1;::::0;10339:18:1;107139:69:0::1;;;;;;;106923:292;;106792:423:::0;;;:::o;72075:133::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;72167:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;72075:133::o;69303:198::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7371:2:1;68625:68:0;;;7353:21:1;;;7390:18;;;7383:30;7449:34;7429:18;;;7422:62;7501:18;;68625:68:0;7169:356:1;68625:68:0;69391:22:::1;::::0;::::1;69383:73;;;::::0;-1:-1:-1;;;69383:73:0;;10647:2:1;69383:73:0::1;::::0;::::1;10629:21:1::0;10686:2;10666:18;;;10659:30;10725:34;10705:18;;;10698:62;10796:8;10776:18;;;10769:36;10822:19;;69383:73:0::1;10445:402:1::0;69383:73:0::1;69466:28;69485:8;69466:18;:28::i;102749:731::-:0;102825:13;102842:31;102860:12;102842:17;:31::i;:::-;102822:51;;;102883:19;102905:25;:5;:23;;;;:25::i;:::-;102883:47;;102964:11;102948:27;;:12;:27;;;102940:68;;;;-1:-1:-1;;;102940:68:0;;11054:2:1;102940:68:0;;;11036:21:1;11093:2;11073:18;;;11066:30;11132;11112:18;;;11105:58;11180:18;;102940:68:0;10852:352:1;102940:68:0;103018:12;103033:24;-1:-1:-1;;103033:22:0;;;:24::i;:::-;103116:28;;;;103067:34;103116:28;;;:14;:28;;;;;;;;;103104:41;;:11;:41;;;;;103171:13;;103018:39;;-1:-1:-1;103104:41:0;103171:13;;103163:21;;;;103155:65;;;;-1:-1:-1;;;103155:65:0;;11411:2:1;103155:65:0;;;11393:21:1;11450:2;11430:18;;;11423:30;11489:33;11469:18;;;11462:61;11540:18;;103155:65:0;11209:355:1;103155:65:0;103230:15;103248:23;-1:-1:-1;;103248:21:0;;;:23::i;:::-;82940:24;;;;:17;;;:24;;;;;103311:15;82940:37;;103230:41;-1:-1:-1;82774:22:0;;;;;;;;;;103427:7;103420:5;103399:74;;103406:12;103399:74;;;103436:36;:28;:5;:26;;;;:28::i;:36::-;103399:74;;;;;;:::i;:::-;;;;;;;;102812:668;;;;;102749:731;:::o;87166:614::-;87345:5;87306:16;87361:413;83559:2;87381:1;:14;87361:413;;;87447:4;87432:11;;;87431:20;87413:15;87481:7;87442:1;87481:10;;;;;;;:::i;:::-;;;;;87465:26;;87509:7;87520:1;87509:12;87505:200;;87562:33;;;;;;12137:19:1;;;12172:12;;;12165:28;;;12209:12;;87562:33:0;;;;;;;;;;;;87552:44;;;;;;87541:55;;87505:200;;;87656:33;;;;;;12137:19:1;;;12172:12;;;12165:28;;;12209:12;;87656:33:0;;;;;;;;;;;;87646:44;;;;;;87635:55;;87505:200;-1:-1:-1;;87746:3:0;;87361:413;;;;87166:614;;;;;:::o;63493:808::-;63557:4;63890:13;;;;;;;63886:409;;;63944:7;:12;;63955:1;63944:12;:61;;;;-1:-1:-1;63999:4:0;54747:19;:23;63944:61;63919:166;;;;-1:-1:-1;;;63919:166:0;;12434:2:1;63919:166:0;;;12416:21:1;12473:2;12453:18;;;12446:30;12512:34;12492:18;;;12485:62;12583:16;12563:18;;;12556:44;12617:19;;63919:166:0;12232:410:1;63919:166:0;-1:-1:-1;64106:5:0;;63493:808;-1:-1:-1;63493:808:0:o;63886:409::-;64150:12;;:22;;;;:12;;:22;64142:81;;;;-1:-1:-1;;;64142:81:0;;12434:2:1;64142:81:0;;;12416:21:1;12473:2;12453:18;;;12446:30;12512:34;12492:18;;;12485:62;12583:16;12563:18;;;12556:44;12617:19;;64142:81:0;12232:410:1;64142:81:0;-1:-1:-1;64237:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;63493:808:0:o;63886:409::-;63493:808;;;:::o;71611:142::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;12849:2:1;62896:69:0;;;12831:21:1;12888:2;12868:18;;;12861:30;12927:34;12907:18;;;12900:62;12998:13;12978:18;;;12971:41;13029:19;;62896:69:0;12647:407:1;62896:69:0;71699:16:::1;:14;:16::i;37137:126::-:0;37204:7;37230:26;:8;34725:4;37230:12;:26::i;:::-;37223:33;37137:126;-1:-1:-1;;37137:126:0:o;37387:305::-;37466:7;37447:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;37504:181:::1;37530:8;37556:35;37568:8;37578:12;37556:11;:35::i;:::-;37609:33;37621:8;37631:10;37609:11;:33::i;:::-;34781:12;37504:8;:181::i;:::-;37485:200;;35009:1;37387:305:::0;;;;:::o;40989:151::-;41065:6;41047:7;40069:37;34781:12;34774:20;-1:-1:-1;;40069:16:0;;;;:37::i;:::-;-1:-1:-1;41097:35:0::1;-1:-1:-1::0;;41097:17:0;::::1;39748:1;41130;41097:17;:35::i;41590:161::-:0;41671:6;41653:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41703:40:0::1;-1:-1:-1::0;;41703:17:0;::::1;39900:2;41741:1;41703:17;:40::i;23211:290::-:0;23267:14;23293:12;23308;23312:7;16142:3;16138:17;3426:26;16134:29;;15815:364;23308:12;23293:27;;;;23330:12;23345;23349:7;17248:2;17244:16;3426:26;17240:28;;17002:282;23345:12;23330:27;;23464:21;;;;23211:290;-1:-1:-1;;;23211:290:0:o;83310:182::-;83381:4;83404:36;;;;;:81;;-1:-1:-1;;81631:1:0;83444:41;;;83310:182::o;42028:174::-;42115:6;42097:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;42147:47:0::1;-1:-1:-1::0;;42147:17:0;::::1;40015:2;42192:1;42147:17;:47::i;37814:299::-:0;37891:7;37872:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;37929:177:::1;37955:8;37981:33;37993:8;38003:10;37981:11;:33::i;:::-;38032;38044:8;38054:10;38032:11;:33::i;:::-;34844:10;37504:8;:181::i;41817:147::-:0;41896:7;41878;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41922:35:0::1;-1:-1:-1::0;;41922:13:0;::::1;39953:2;41954;41922:13;:35::i;110792:643::-:0;110867:17;110969:41;;;110965:464;;-1:-1:-1;;111272:15:0;;;;;63493:808::o;110965:464::-;111407:10;111380:38;34011:127;41384:149;41459:6;41441:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41491:34:0::1;-1:-1:-1::0;;41491:17:0;::::1;39845:2;41523:1;41491:17;:34::i;41192:141::-:0;41268:7;41250;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41294:32:0::1;-1:-1:-1::0;;41294:13:0;::::1;39797:1;41323:2;41294:13;:32::i;38235:190::-:0;38312:7;38293:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;38338:80:::1;38347:8;38357:33;38369:8;38379:10;38357:11;:33::i;:::-;17248:2:::0;17244:16;;;3426:26;17240:28;34905:10:::1;37504:8;:181::i;29064:632::-:0;29119:16;29147:11;29168:12;29183;29187:7;17248:2;17244:16;3426:26;17240:28;;17002:282;29183:12;29168:27;;;;29305:4;29299:11;29292:18;;29360:3;29353:10;;29406:33;29419:7;29428:3;29434:4;29428:10;29406:12;:33::i;:::-;-1:-1:-1;29563:14:0;;;29579:4;29559:25;29553:4;29546:39;29626:17;;29064:632;;-1:-1:-1;29064:632:0:o;72505:179::-;72588:7;;;;72605:21;;;;;;;;;;;72641:36;;;72588:7;;;;13294:34:1;;;13359:2;13344:18;;13337:43;;;;72641:36:0;;13206:18:1;72641:36:0;;;;;;;72556:128;72505:179;:::o;82809:175::-;82940:24;;;;:17;;;;:24;;;;;:37;82809:175::o;69655:187::-;69747:6;;;;69763:17;;;;;;;;;;;69795:40;;69747:6;;;69763:17;69747:6;;69795:40;;69728:16;;69795:40;69718:124;69655:187;:::o;78985:474::-;79086:16;;79141:19;:12;79086:16;79141;:19::i;:::-;79133:27;-1:-1:-1;73658:2:0;3426:26;17248:2;17244:16;;;17240:28;74912:37;79170:52;;;;-1:-1:-1;;;79170:52:0;;13593:2:1;79170:52:0;;;13575:21:1;13632:2;13612:18;;;13605:30;13671:20;13651:18;;;13644:48;13709:18;;79170:52:0;13391:342:1;79170:52:0;79243:115;79275:23;-1:-1:-1;;79275:21:0;;;:23::i;:::-;79312:36;:28;-1:-1:-1;;79312:26:0;;;:28::i;:36::-;79243:18;:115::i;:::-;79232:126;-1:-1:-1;79376:47:0;79387:25;-1:-1:-1;;79387:23:0;;;:25::i;:::-;-1:-1:-1;110667:7:0;;;110655:19;;;110667:7;;110655:19;;110554:127;79376:47;79368:84;;;;-1:-1:-1;;;79368:84:0;;13940:2:1;79368:84:0;;;13922:21:1;13979:2;13959:18;;;13952:30;14018:26;13998:18;;;13991:54;14062:18;;79368:84:0;13738:348:1;79368:84:0;78985:474;;;:::o;75053:143::-;75118:6;75150:38;-1:-1:-1;;75150:15:0;;75118:6;75186:1;75150:15;:38::i;75310:136::-;75374:6;75406:32;-1:-1:-1;;75406:15:0;;73552:1;;75406:15;:32::i;75539:124::-;75602:7;75628:28;-1:-1:-1;;75628:11:0;;73599:1;75653:2;75628:11;:28::i;76007:172::-;76075:7;76101:71;73658:2;76131:37;73658:2;17248;17244:16;;;3426:26;17240:28;76131:37;:::i;:::-;-1:-1:-1;;76101:11:0;;;:71;76170:1;76101:11;:71::i;68133:95::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;12849:2:1;62896:69:0;;;12831:21:1;12888:2;12868:18;;;12861:30;12927:34;12907:18;;;12900:62;12998:13;12978:18;;;12971:41;13029:19;;62896:69:0;12647:407:1;62896:69:0;68195:26:::1;:24;:26::i;14411:359::-:0;14515:10;;14481:7;;14662:4;14653:14;;14737:26;;;;14653:14;14515:10;14737:5;:26::i;:::-;14730:33;14411:359;-1:-1:-1;;;;;14411:359:0:o;10829:578::-;10907:7;10931:26;10938:7;10947:9;10931:6;:26::i;:::-;10926:451;;10976:9;10989:35;11007:15;11014:7;15173:3;15169:17;;14962:268;11007:15;10999:24;;10989:9;:35::i;:::-;10973:51;;;11041:9;11054:29;11072:9;11064:18;;11054:9;:29::i;:::-;11141:186;;14588:31:1;11141:186:0;;;14576:44:1;14639:66;14743:3;14739:16;;;14735:25;;14721:12;;;14714:47;14791:15;14777:12;;;14770:37;14841:16;;;14837:25;14823:12;;;14816:47;11038:45:0;;-1:-1:-1;11097:17:0;;-1:-1:-1;14879:12:1;;11141:186:0;;;;;;;;;;;;11097:244;;11362:3;11355:11;;-1:-1:-1;;;11355:11:0;;;;;;;;:::i;10926:451::-;-1:-1:-1;11393:7:0;;10829:578;-1:-1:-1;10829:578:0:o;38947:164::-;39021:7;39047:57;35651:1;39074:5;39066:14;;;;;;;;:::i;:::-;:26;;;;:::i;:::-;-1:-1:-1;;39047:18:0;;;35651:1;39047:18;:57::i;38662:218::-;38803:7;38829:44;38844:5;38851:11;38844:5;38851:3;:11;:::i;:::-;-1:-1:-1;;38829:14:0;;;:44;38864:8;38829:14;:44::i;21877:221::-;21996:14;22074:11;22079:6;22074:2;:11;:::i;:::-;22073:17;;22089:1;22073:17;:::i;:::-;22029:62;;22037:30;22043:7;22052:6;22060;22037:5;:30::i;:::-;22029:62;;;21877:221;-1:-1:-1;;;;21877:221:0:o;20760:771::-;20875:14;20905:6;:11;;20915:1;20905:11;20901:59;;-1:-1:-1;20947:1:0;20932:17;;20901:59;20991:12;20995:7;17248:2;17244:16;3426:26;17240:28;;17002:282;20991:12;20973:30;;:15;;;;:6;:15;:::i;:::-;:30;20969:137;;;21026:68;21042:12;21046:7;16142:3;16138:17;3426:26;16134:29;;15815:364;21042:12;21026:68;;21056:12;21060:7;17248:2;17244:16;3426:26;17240:28;;17002:282;21056:12;21026:68;;21070:6;21086;21078:15;;21026;:68::i;:::-;21019:76;;-1:-1:-1;;;21019:76:0;;;;;;;;:::i;20969:137::-;21133:2;21123:6;:12;;;;21115:83;;;;-1:-1:-1;;;21115:83:0;;16004:2:1;21115:83:0;;;15986:21:1;16043:2;16023:18;;;16016:30;16082:34;16062:18;;;16055:62;16153:28;16133:18;;;16126:56;16199:19;;21115:83:0;15802:422:1;21115:83:0;21279:1;21270:10;;21209:15;21315:12;21319:7;16142:3;16138:17;3426:26;16134:29;;15815:364;21315:12;21300:27;;;-1:-1:-1;21337:13:0;8244:66;8214:12;;;8193:131;21489:17;;;;21483:24;21479:36;;;-1:-1:-1;;;;;20760:771:0:o;27792:902::-;27870:15;-1:-1:-1;;8728:15:0;;;;27897:69;;;;-1:-1:-1;;;27897:69:0;;16431:2:1;27897:69:0;;;16413:21:1;16470:2;16450:18;;;16443:30;16509:34;16489:18;;;16482:62;16580:10;16560:18;;;16553:38;16608:19;;27897:69:0;16229:404:1;27897:69:0;27984:16;27992:7;27984;:16::i;:::-;27976:72;;;;-1:-1:-1;;;27976:72:0;;16840:2:1;27976:72:0;;;16822:21:1;16879:2;16859:18;;;16852:30;16918:34;16898:18;;;16891:62;16989:13;16969:18;;;16962:41;17020:19;;27976:72:0;16638:407:1;27976:72:0;28058:12;28073;28077:7;17248:2;17244:16;3426:26;17240:28;;17002:282;28073:12;28058:27;;;;28095:15;28113:12;28117:7;16142:3;16138:17;3426:26;16134:29;;15815:364;28113:12;28095:30;;;;28136:11;28257:4;28251:11;28244:18;;28344:7;28339:3;28336:16;28333:94;;;28384:4;28378;28371:18;28333:94;28599:4;28590:7;28584:4;28575:7;28572:1;28565:5;28554:50;28550:55;28635:52;28656:15;28663:7;15173:3;15169:17;;14962:268;28656:15;12817:27;12821:2;12817:27;;;;12891:17;;12883:26;;12955:17;;12951:2;12947:26;;12567:446;28635:52;28625:62;27792:902;-1:-1:-1;;;;;;27792:902:0:o;75769:155::-;75832:7;75858:59;-1:-1:-1;;75858:11:0;;75832:7;73658:2;75832:7;75858:11;:59::i;76506:285::-;76616:14;;76663;-1:-1:-1;;76663:12:0;;;:14::i;:::-;76646:31;;76696:36;76725:6;52241:58;;18807:66:1;52241:58:0;;;18795:79:1;18890:12;;;18883:28;;;52111:7:0;;18927:12:1;;52241:58:0;;;;;;;;;;;;52231:69;;;;;;52224:76;;52042:265;;;;76696:36;76687:45;;76751:33;76765:6;76773:10;76751:13;:33::i;17885:399::-;18024:7;18043:12;18058;18062:7;16142:3;16138:17;3426:26;16134:29;;15815:364;18058:12;18043:27;;;;18154:12;18158:7;18154:3;:12::i;:::-;18147:4;18131:13;18138:6;18131:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;18127:77;;;-1:-1:-1;;18182:11:0;;;;;18127:77;18221:13;18228:6;18221:4;:13;:::i;:::-;18214:20;;18251:26;18257:7;18251:26;;18266:4;18272;18251:5;:26::i;68234:111::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;12849:2:1;62896:69:0;;;12831:21:1;12888:2;12868:18;;;12861:30;12927:34;12907:18;;;12900:62;12998:13;12978:18;;;12971:41;13029:19;;62896:69:0;12647:407:1;62896:69:0;68306:32:::1;67421:10:::0;68306:18:::1;:32::i;13552:462::-:0;13663:15;;13705:11;13712:4;13705;:11;:::i;:::-;13690:26;;13831:4;13825:11;13819:4;13816:21;13813:66;;;-1:-1:-1;13864:1:0;13813:66;13902:4;13910:1;13902:9;13898:51;;-1:-1:-1;;13927:11:0;;;;;13898:51;-1:-1:-1;;12821:2:0;12817:27;;;12891:17;;;;12883:26;;;12955:17;12951:2;12947:26;;13552:462::o;10399:132::-;10473:4;10515:9;10496:28;;:15;10503:7;15173:3;15169:17;;14962:268;10496:15;:28;;;;10399:132;-1:-1:-1;;;10399:132:0:o;5787:667::-;5841:13;;5897:2;5882:258;5905:2;5901:1;:6;;;5882:258;;;5925:11;5952:5;:1;5956;5952:5;:::i;:::-;5945:13;;:2;:13;;5925:34;;5982:14;5990:5;5982:7;:14::i;:::-;5973:23;;;;;;6014:1;:7;;6019:2;6014:7;6010:58;;6051:2;6041:12;;;;;6010:58;-1:-1:-1;6109:6:0;;5882:258;;;-1:-1:-1;6203:2:0;6188:260;6211:3;6207:1;:7;;;6188:260;;;6232:11;6259:5;:1;6263;6259:5;:::i;:::-;6252:13;;:2;:13;;6232:34;;6290:14;6298:5;6290:7;:14::i;:::-;6280:24;;;;;;6322:1;:6;;6327:1;6322:6;6318:58;;6359:2;6348:13;;;;;6318:58;-1:-1:-1;6417:6:0;;6188:260;;;;5787:667;;;:::o;19517:741::-;19663:17;19695:9;19708:15;19718:4;19708:9;:15::i;:::-;19692:31;;;19736:9;19749:15;19759:4;19749:9;:15::i;:::-;19733:31;;;19777:9;19790:17;19800:6;19790:9;:17::i;:::-;19774:33;;;19820:9;19833:17;19843:6;19833:9;:17::i;:::-;19817:33;;;20000:1;20062;20142;20204;19886:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19860:391;;19682:576;;;;19517:741;;;;;;:::o;9401:333::-;9458:8;9482:15;9489:7;15173:3;15169:17;;14962:268;9482:15;:31;;9501:12;9482:31;9478:74;;-1:-1:-1;9536:5:0;;9401:333;-1:-1:-1;9401:333:0:o;9478:74::-;9561:12;9576;9580:7;9576:3;:12::i;:::-;9711:4;9705:11;-1:-1:-1;9692:26:0;;9401:333;-1:-1:-1;;;9401:333:0:o;48338:227::-;48416:7;48436:17;48455:18;48477:27;48488:4;48494:9;48477:10;:27::i;:::-;48435:69;;;;48514:18;48526:5;48514:11;:18::i;17458:147::-;17511:7;17576:12;17580:7;17248:2;17244:16;3426:26;17240:28;;17002:282;17576:12;17561;17565:7;16142:3;16138:17;3426:26;16134:29;;15815:364;17561:12;:27;17554:34;;;;17458:147;;;:::o;5264:199::-;5314:14;5351:18;5367:1;5361:2;:7;;;;5351:9;:18::i;:::-;5340:29;;5393:13;;;;;;5405:1;5393:13;5427;5437:2;5427:9;:13::i;:::-;5416:24;;;;5264:199;-1:-1:-1;5264:199:0:o;46273:1279::-;46354:7;46363:12;46584:9;:16;46604:2;46584:22;46580:966;;46873:4;46858:20;;46852:27;46922:4;46907:20;;46901:27;46979:4;46964:20;;46958:27;46622:9;46950:36;47020:25;47031:4;46950:36;46852:27;46901;47020:10;:25::i;:::-;47013:32;;;;;;;;;46580:966;47066:9;:16;47086:2;47066:22;47062:484;;47335:4;47320:20;;47314:27;47385:4;47370:20;;47364:27;47425:23;47436:4;47314:27;47364;47425:10;:23::i;:::-;47418:30;;;;;;;;47062:484;-1:-1:-1;47495:1:0;;-1:-1:-1;47499:35:0;47062:484;46273:1279;;;;;:::o;44578:631::-;44655:20;44646:5;:29;;;;;;;;:::i;:::-;;44642:561;;44578:631;:::o;44642:561::-;44751:29;44742:5;:38;;;;;;;;:::i;:::-;;44738:465;;44796:34;;-1:-1:-1;;;44796:34:0;;19152:2:1;44796:34:0;;;19134:21:1;19191:2;19171:18;;;19164:30;19230:26;19210:18;;;19203:54;19274:18;;44796:34:0;18950:348:1;44738:465:0;44860:35;44851:5;:44;;;;;;;;:::i;:::-;;44847:356;;44911:41;;-1:-1:-1;;;44911:41:0;;19505:2:1;44911:41:0;;;19487:21:1;19544:2;19524:18;;;19517:30;19583:33;19563:18;;;19556:61;19634:18;;44911:41:0;19303:355:1;44847:356:0;44982:30;44973:5;:39;;;;;;;;:::i;:::-;;44969:234;;45028:44;;-1:-1:-1;;;45028:44:0;;19865:2:1;45028:44:0;;;19847:21:1;19904:2;19884:18;;;19877:30;19943:34;19923:18;;;19916:62;20014:4;19994:18;;;19987:32;20036:19;;45028:44:0;19663:398:1;44969:234:0;45102:30;45093:5;:39;;;;;;;;:::i;:::-;;45089:114;;45148:44;;-1:-1:-1;;;45148:44:0;;20268:2:1;45148:44:0;;;20250:21:1;20307:2;20287:18;;;20280:30;20346:34;20326:18;;;20319:62;20417:4;20397:18;;;20390:32;20439:19;;45148:44:0;20066:398:1;3699:1393:0;3751:10;3917:4;3912:9;;;;3963:15;;;;;3959:57;;-1:-1:-1;4001:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;3959:57::-;4034:7;:15;;4045:4;4034:15;4030:57;;-1:-1:-1;4072:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4030:57::-;4105:7;:15;;4116:4;4105:15;4101:57;;-1:-1:-1;4143:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4101:57::-;4176:7;:15;;4187:4;4176:15;4172:57;;-1:-1:-1;4214:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4172:57::-;4247:7;:15;;4258:4;4247:15;4243:57;;-1:-1:-1;4285:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4243:57::-;4318:7;:15;;4329:4;4318:15;4314:57;;-1:-1:-1;4356:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4314:57::-;4389:7;:15;;4400:4;4389:15;4385:57;;-1:-1:-1;4427:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4385:57::-;4460:7;:15;;4471:4;4460:15;4456:57;;-1:-1:-1;4498:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4456:57::-;4531:7;:15;;4542:4;4531:15;4527:57;;-1:-1:-1;4569:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4527:57::-;4602:7;:15;;4613:4;4602:15;4598:57;;-1:-1:-1;4640:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4598:57::-;4673:7;:15;;4684:4;4673:15;4669:57;;-1:-1:-1;4711:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4669:57::-;4744:7;:15;;4755:4;4744:15;4740:57;;-1:-1:-1;4782:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4740:57::-;4815:7;:15;;4826:4;4815:15;4811:57;;-1:-1:-1;4853:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4811:57::-;4886:7;:15;;4897:4;4886:15;4882:57;;-1:-1:-1;4924:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4882:57::-;4957:7;:15;;4968:4;4957:15;4953:57;;-1:-1:-1;4995:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4953:57::-;5028:7;:15;;5039:4;5028:15;5024:57;;-1:-1:-1;5066:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;49746:1603::-;49872:7;;50796:66;50783:79;;50779:161;;;-1:-1:-1;50894:1:0;;-1:-1:-1;50898:30:0;50878:51;;50779:161;50953:1;:7;;50958:2;50953:7;;:18;;;;;50964:1;:7;;50969:2;50964:7;;50953:18;50949:100;;;-1:-1:-1;51003:1:0;;-1:-1:-1;51007:30:0;50987:51;;50949:100;51160:24;;;51143:14;51160:24;;;;;;;;;20696:25:1;;;20769:4;20757:17;;20737:18;;;20730:45;;;;20791:18;;;20784:34;;;20834:18;;;20827:34;;;51160:24:0;;20668:19:1;;51160:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51160:24:0;;;;;;-1:-1:-1;;51198:20:0;;;51194:101;;51250:1;51254:29;51234:50;;;;;;;51194:101;51313:6;-1:-1:-1;51321:20:0;;-1:-1:-1;49746:1603:0;;;;;;;;:::o;48819:336::-;48929:7;;48987:66;48974:80;;48929:7;49080:25;49096:3;49081:18;;;49103:2;49080:25;:::i;:::-;49064:42;;49123:25;49134:4;49140:1;49143;49146;49123:10;:25::i;:::-;49116:32;;;;;;48819:336;;;;;;:::o;14:163:1:-;81:20;;141:10;130:22;;120:33;;110:61;;167:1;164;157:12;182:324;257:6;265;273;326:2;314:9;305:7;301:23;297:32;294:52;;;342:1;339;332:12;294:52;365:28;383:9;365:28;:::i;:::-;355:38;;412:37;445:2;434:9;430:18;412:37;:::i;:::-;402:47;;496:2;485:9;481:18;468:32;458:42;;182:324;;;;;:::o;703:184::-;755:77;752:1;745:88;852:4;849:1;842:15;876:4;873:1;866:15;892:777;934:5;987:3;980:4;972:6;968:17;964:27;954:55;;1005:1;1002;995:12;954:55;1041:6;1028:20;1067:18;1104:2;1100;1097:10;1094:36;;;1110:18;;:::i;:::-;1244:2;1238:9;1306:4;1298:13;;1149:66;1294:22;;;1318:2;1290:31;1286:40;1274:53;;;1342:18;;;1362:22;;;1339:46;1336:72;;;1388:18;;:::i;:::-;1428:10;1424:2;1417:22;1463:2;1455:6;1448:18;1509:3;1502:4;1497:2;1489:6;1485:15;1481:26;1478:35;1475:55;;;1526:1;1523;1516:12;1475:55;1590:2;1583:4;1575:6;1571:17;1564:4;1556:6;1552:17;1539:54;1637:1;1630:4;1625:2;1617:6;1613:15;1609:26;1602:37;1657:6;1648:15;;;;;;892:777;;;;:::o;1674:609::-;1794:6;1802;1810;1818;1871:4;1859:9;1850:7;1846:23;1842:34;1839:54;;;1889:1;1886;1879:12;1839:54;1912:28;1930:9;1912:28;:::i;:::-;1902:38;;1991:2;1980:9;1976:18;1963:32;2018:18;2010:6;2007:30;2004:50;;;2050:1;2047;2040:12;2004:50;2073:49;2114:7;2105:6;2094:9;2090:22;2073:49;:::i;:::-;2063:59;;;2156:4;2145:9;2141:20;2180:7;2176:2;2173:15;2170:35;;;2201:1;2198;2191:12;2170:35;1674:609;;;;-1:-1:-1;;;2239:2:1;2224:18;;;;;2261:16;;;1674:609::o;2288:252::-;2355:6;2363;2416:2;2404:9;2395:7;2391:23;2387:32;2384:52;;;2432:1;2429;2422:12;2384:52;2455:28;2473:9;2455:28;:::i;:::-;2445:38;2530:2;2515:18;;;;2502:32;;-1:-1:-1;;;2288:252:1:o;2909:154::-;2995:42;2988:5;2984:54;2977:5;2974:65;2964:93;;3053:1;3050;3043:12;3068:319;3135:6;3143;3196:2;3184:9;3175:7;3171:23;3167:32;3164:52;;;3212:1;3209;3202:12;3164:52;3235:28;3253:9;3235:28;:::i;:::-;3225:38;;3313:2;3302:9;3298:18;3285:32;3326:31;3351:5;3326:31;:::i;:::-;3376:5;3366:15;;;3068:319;;;;;:::o;3820:320::-;3888:6;3941:2;3929:9;3920:7;3916:23;3912:32;3909:52;;;3957:1;3954;3947:12;3909:52;3997:9;3984:23;4030:18;4022:6;4019:30;4016:50;;;4062:1;4059;4052:12;4016:50;4085:49;4126:7;4117:6;4106:9;4102:22;4085:49;:::i;4145:247::-;4204:6;4257:2;4245:9;4236:7;4232:23;4228:32;4225:52;;;4273:1;4270;4263:12;4225:52;4312:9;4299:23;4331:31;4356:5;4331:31;:::i;4397:320::-;4473:6;4481;4489;4542:2;4530:9;4521:7;4517:23;4513:32;4510:52;;;4558:1;4555;4548:12;4510:52;4581:28;4599:9;4581:28;:::i;:::-;4571:38;4656:2;4641:18;;4628:32;;-1:-1:-1;4707:2:1;4692:18;;;4679:32;;4397:320;-1:-1:-1;;;4397:320:1:o;4722:184::-;4780:6;4833:2;4821:9;4812:7;4808:23;4804:32;4801:52;;;4849:1;4846;4839:12;4801:52;4872:28;4890:9;4872:28;:::i;5629:184::-;5681:77;5678:1;5671:88;5778:4;5775:1;5768:15;5802:4;5799:1;5792:15;5818:128;5858:3;5889:1;5885:6;5882:1;5879:13;5876:39;;;5895:18;;:::i;:::-;-1:-1:-1;5931:9:1;;5818:128::o;5951:184::-;6003:77;6000:1;5993:88;6100:4;6097:1;6090:15;6124:4;6121:1;6114:15;9105:530;9146:3;9184:5;9178:12;9211:6;9206:3;9199:19;9236:1;9246:162;9260:6;9257:1;9254:13;9246:162;;;9322:4;9378:13;;;9374:22;;9368:29;9350:11;;;9346:20;;9339:59;9275:12;9246:162;;;9426:6;9423:1;9420:13;9417:87;;;9492:1;9485:4;9476:6;9471:3;9467:16;9463:27;9456:38;9417:87;-1:-1:-1;9549:2:1;9537:15;9554:66;9533:88;9524:98;;;;9624:4;9520:109;;9105:530;-1:-1:-1;;9105:530:1:o;9640:547::-;9858:4;9887:10;9936:2;9928:6;9924:15;9913:9;9906:34;9988:2;9980:6;9976:15;9971:2;9960:9;9956:18;9949:43;;10028:6;10023:2;10012:9;10008:18;10001:34;10071:6;10066:2;10055:9;10051:18;10044:34;10115:3;10109;10098:9;10094:19;10087:32;10136:45;10176:3;10165:9;10161:19;10153:6;10136:45;:::i;:::-;10128:53;9640:547;-1:-1:-1;;;;;;;9640:547:1:o;11569:217::-;11716:2;11705:9;11698:21;11679:4;11736:44;11776:2;11765:9;11761:18;11753:6;11736:44;:::i;11791:184::-;11843:77;11840:1;11833:88;11940:4;11937:1;11930:15;11964:4;11961:1;11954:15;14091:125;14131:4;14159:1;14156;14153:8;14150:34;;;14164:18;;:::i;:::-;-1:-1:-1;14201:9:1;;14091:125::o;15126:228::-;15166:7;15292:1;15224:66;15220:74;15217:1;15214:81;15209:1;15202:9;15195:17;15191:105;15188:131;;;15299:18;;:::i;:::-;-1:-1:-1;15339:9:1;;15126:228::o;15359:195::-;15397:4;15434;15431:1;15427:12;15466:4;15463:1;15459:12;15491:3;15486;15483:12;15480:38;;;15498:18;;:::i;:::-;15535:13;;;15359:195;-1:-1:-1;;;15359:195:1:o;15559:238::-;15597:7;15637:4;15634:1;15630:12;15669:4;15666:1;15662:12;15729:3;15723:4;15719:14;15714:3;15711:23;15704:3;15697:11;15690:19;15686:49;15683:75;;;15738:18;;:::i;:::-;15778:13;;15559:238;-1:-1:-1;;;15559:238:1:o;17169:1391::-;17891:34;17879:47;;17956:23;17951:2;17942:12;;17935:45;17999:66;18103:3;18099:16;;;18095:25;;18090:2;18081:12;;18074:47;18140:17;18182:2;18173:12;;18166:24;;;18224:16;;;18220:25;;18215:2;18206:12;;18199:47;18276:34;18271:2;18262:12;;18255:56;18342:3;18336;18327:13;;18320:26;18381:16;;;18377:25;;18371:3;18362:13;;18355:48;18428:3;18419:13;;18412:25;18472:16;;;18468:25;18462:3;18453:13;;18446:48;17127:3;18549;18540:13;;17115:16;-1:-1:-1;17147:11:1;;;18510:44;17050:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"Process","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"previousConfirmAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newConfirmAt","type":"uint256"}],"name":"SetConfirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"acceptableRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"activeReplicaConfirmedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_messageId","type":"bytes32"}],"name":"activeReplicaMessageStatus","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"}],"name":"activeReplicaNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"process","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"prove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"proveAndProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"uint256","name":"_confirmAt","type":"uint256"}],"name":"setConfirmation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"submitAttestation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"Process(uint32,bytes32)":{"notice":"Emitted when message is processed"},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"notice":"Emitted when a root's confirmation is modified by governance"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"}},"kind":"user","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"notice":"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed"},"initialize(uint32,address)":{"notice":"Initialize the replica"},"process(bytes)":{"notice":"Given formatted message, attempts to dispatch message payload to end recipient."},"prove(uint32,bytes,bytes32[32],uint256)":{"notice":"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf."},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"notice":"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message."},"setConfirmation(uint32,bytes32,uint256)":{"notice":"Set confirmAt for a given root"},"setUpdater(address)":{"notice":"Set Updater role"},"submitAttestation(bytes)":{"notice":"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event."}},"version":1},"developerDoc":{"events":{"Process(uint32,bytes32)":{"params":{"messageHash":"The keccak256 hash of the message that was processed"}},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"params":{"newConfirmAt":"The new value of confirmAt","previousConfirmAt":"The previous value of confirmAt","root":"The root for which confirmAt has been set"}}},"kind":"dev","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"params":{"_root":"the Merkle root, submitted in an update, to check"},"returns":{"_0":"TRUE iff root has been submitted \u0026 timeout has expired"}},"initialize(uint32,address)":{"details":"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer","params":{"_remoteDomain":"The domain of the Home contract this follows","_updater":"The EVM id of the updater"}},"owner()":{"details":"Returns the address of the current owner."},"process(bytes)":{"details":"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.","params":{"_message":"Formatted message"}},"prove(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message","_proof":"Merkle proof of inclusion for leaf"},"returns":{"_0":"Returns true if proof was valid and `prove` call succeeded*"}},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if `prove` call returns false","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message (refer to UpdaterStorage.sol Message library)","_proof":"Merkle proof of inclusion for message's leaf"}},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setConfirmation(uint32,bytes32,uint256)":{"details":"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)","params":{"_confirmAt":"The new confirmation time. Set to 0 to \"delete\" a root.","_root":"The root for which to modify confirm time"}},"setUpdater(address)":{"details":"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)","params":{"_updater":"New Updater"}},"submitAttestation(bytes)":{"details":"Reverts if update doesn't build off latest committedRoot or if signature is invalid.","params":{"_attestation":"Attestation data and signature"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Process(uint32,bytes32)\":{\"params\":{\"messageHash\":\"The keccak256 hash of the message that was processed\"}},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"params\":{\"newConfirmAt\":\"The new value of confirmAt\",\"previousConfirmAt\":\"The previous value of confirmAt\",\"root\":\"The root for which confirmAt has been set\"}}},\"kind\":\"dev\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"params\":{\"_root\":\"the Merkle root, submitted in an update, to check\"},\"returns\":{\"_0\":\"TRUE iff root has been submitted \u0026 timeout has expired\"}},\"initialize(uint32,address)\":{\"details\":\"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer\",\"params\":{\"_remoteDomain\":\"The domain of the Home contract this follows\",\"_updater\":\"The EVM id of the updater\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"process(bytes)\":{\"details\":\"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.\",\"params\":{\"_message\":\"Formatted message\"}},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message\",\"_proof\":\"Merkle proof of inclusion for leaf\"},\"returns\":{\"_0\":\"Returns true if proof was valid and `prove` call succeeded*\"}},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if `prove` call returns false\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message (refer to UpdaterStorage.sol Message library)\",\"_proof\":\"Merkle proof of inclusion for message's leaf\"}},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"details\":\"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)\",\"params\":{\"_confirmAt\":\"The new confirmation time. Set to 0 to \\\"delete\\\" a root.\",\"_root\":\"The root for which to modify confirm time\"}},\"setUpdater(address)\":{\"details\":\"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)\",\"params\":{\"_updater\":\"New Updater\"}},\"submitAttestation(bytes)\":{\"details\":\"Reverts if update doesn't build off latest committedRoot or if signature is invalid.\",\"params\":{\"_attestation\":\"Attestation data and signature\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"Process(uint32,bytes32)\":{\"notice\":\"Emitted when message is processed\"},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"notice\":\"Emitted when a root's confirmation is modified by governance\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"}},\"kind\":\"user\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"notice\":\"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed\"},\"initialize(uint32,address)\":{\"notice\":\"Initialize the replica\"},\"process(bytes)\":{\"notice\":\"Given formatted message, attempts to dispatch message payload to end recipient.\"},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf.\"},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message.\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"notice\":\"Set confirmAt for a given root\"},\"setUpdater(address)\":{\"notice\":\"Set Updater role\"},\"submitAttestation(bytes)\":{\"notice\":\"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ReplicaManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74","acceptableRoot(uint32,uint32,bytes32)":"15a046aa","activeReplicaConfirmedAt(uint32,bytes32)":"7dfdba28","activeReplicaMessageStatus(uint32,bytes32)":"63415514","activeReplicaNonce(uint32)":"b65672d3","initialize(uint32,address)":"8624c35c","localDomain()":"8d3638f4","owner()":"8da5cb5b","process(bytes)":"928bc4b2","prove(uint32,bytes,bytes32[32],uint256)":"4f63be3f","proveAndProcess(uint32,bytes,bytes32[32],uint256)":"68705275","renounceOwnership()":"715018a6","setConfirmation(uint32,bytes32,uint256)":"9df7d36d","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","submitAttestation(bytes)":"f646a512","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/ReplicaManagerHarness.sol:ReplicaManagerHarness":{"code":"0x60a06040523480156200001157600080fd5b506040516200301c3803806200301c833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612f806200009c600039600081816102a3015281816108b40152610f5b0152612f806000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063928bc4b2116100d8578063bfd84d361161008c578063f2fde38b11610066578063f2fde38b146103ee578063f646a51214610401578063ffa1ad741461041457600080fd5b8063bfd84d361461039b578063ccbdf9c9146103ae578063df034cd0146103ce57600080fd5b80639df7d36d116100bd5780639df7d36d1461033f578063b65672d314610352578063b7bc563e1461038857600080fd5b8063928bc4b2146103195780639d54f4191461032c57600080fd5b8063687052751161013a5780638624c35c116101145780638624c35c1461028b5780638d3638f41461029e5780638da5cb5b146102da57600080fd5b8063687052751461022f578063715018a6146102425780637dfdba281461024a57600080fd5b806348639d241161016b57806348639d24146101c65780634f63be3f146101db57806363415514146101ee57600080fd5b8063089d28941461018757806315a046aa146101a3575b600080fd5b61019060fb5481565b6040519081526020015b60405180910390f35b6101b66101b1366004612948565b61042e565b604051901515815260200161019a565b6101d96101d4366004612984565b61048b565b005b6101b66101e9366004612a77565b610498565b6101906101fc366004612ae7565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b6101d961023d366004612a77565b610612565b6101d9610679565b610190610258366004612ae7565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101d9610299366004612b33565b6106e2565b6102c57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019a565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019a565b6101d9610327366004612b6a565b61085b565b6101d961033a366004612b9f565b610bf9565b6101d961034d366004612bbc565b610c6c565b6102c5610360366004612bef565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101d9610396366004612b9f565b610d60565b6101d96103a9366004612bbc565b610e0e565b6066546102f49073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102f49073ffffffffffffffffffffffffffffffffffffffff1681565b6101d96103fc366004612b9f565b610e3f565b6101d961040f366004612b6a565b610f38565b61041c600081565b60405160ff909116815260200161019a565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361046d576000915050610484565b61047d63ffffffff851682612c39565b4210159150505b9392505050565b610493611113565b60fb55565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff1660028111156104e7576104e7612c51565b146105395760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105975760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e65000000000000000000000000006044820152606401610530565b60006105cd83876020806020026040519081016040528092919082602080028082843760009201919091525089915061117a9050565b60008181526001840160205260409020549091501561060257600092835260029190910160205260409091205550600161060a565b600093505050505b949350505050565b61061e84848484610498565b61066a5760405162461bcd60e51b815260206004820152600660248201527f2170726f766500000000000000000000000000000000000000000000000000006044820152606401610530565b6106738361085b565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106e05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b565b60006106ee6001611234565b9050801561072357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61072c8261138b565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107dd8360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc6020526040902055801561085657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061086682611410565b9050600061087962ffffff198316611424565b9050600061088c62ffffff198316611464565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f0000000000000000000000000000000000000000000000000000000000000000166108e362ffffff19851661148e565b63ffffffff16146109365760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e00000000000000000000000000000000000000006044820152606401610530565b600061094762ffffff1986166114af565b60008181526002840160205260409020549091506109648161150c565b6109b05760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f6365737365640000000000000000000000006044820152606401610530565b6109c9846109c362ffffff198816611520565b8361042e565b610a155760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e647300000000000000000000000000006044820152606401610530565b60c95460ff16600114610a6a5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e74000000000000000000000000000000000000000000006044820152606401610530565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610aa9610aa462ffffff198816611541565b611578565b6000828152600284016020526040812060019055610ad4610acf62ffffff198816611610565b611631565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b0262ffffff198a16611673565b610b1162ffffff198b16611694565b600087815260018a016020526040902054610b3f610b3462ffffff198f166116b5565b62ffffff19166116f4565b6040518663ffffffff1660e01b8152600401610b5f959493929190612ceb565b600060405180830381600087803b158015610b7957600080fd5b505af1158015610b8d573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c605760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b610c6981611747565b50565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cd35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610d16908390869086906117cd16565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dc75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020610856918490849061122016565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ea65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b73ffffffffffffffffffffffffffffffffffffffff8116610f2f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610530565b610c69816117e1565b6000610f4382611858565b9150506000610f578262ffffff1916611979565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610fd45760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e000000006044820152606401610530565b6000610fe562ffffff19841661198d565b63ffffffff808416600090815260cc6020908152604080832054835260cb90915290208054929350918116908316116110605760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e74207374617465006044820152606401610530565b600061107162ffffff1986166119a1565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada91716110f6610b348a62ffffff19166119b6565b6040516111039190612d2b565b60405180910390a4505050505050565b60665473ffffffffffffffffffffffffffffffffffffffff1633146106e05760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610530565b8260005b602081101561121857600183821c1660008583602081106111a1576111a1612d3e565b60200201519050816001036111e157604080516020810183905290810185905260600160405160208183030381529060405280519060200120935061120e565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b505060010161117e565b509392505050565b600091825260029092016020526040902055565b60008054610100900460ff16156112d1578160ff1660011480156112575750303b155b6112c95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610530565b506000919050565b60005460ff80841691161061134e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610530565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114085760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b610c606119e9565b600061141e82610539611a6e565b92915050565b60008161143962ffffff198216610539611a92565b5061145b83611449856001611b93565b611454866002611b93565b6001611bc5565b91505b50919050565b60008161147a60015b62ffffff19831690611a92565b5061145b62ffffff19841660026004611be4565b60008161149b600161146d565b5061145b62ffffff198416602a6004611be4565b6000806114ca8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006114f48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b6000811580159061141e5750506001141590565b60008161152d600161146d565b5061145b62ffffff198416604e6004611be4565b60008161155662ffffff198216610539611a92565b5061145b83611566856002611b93565b611571866003611b93565b6002611bc5565b7f1dad5ea7bf29006ead0af41296d42c169129acd1ec64b3639ebe94b8c01bfa116115a862ffffff198316611c14565b6115b762ffffff198416611c42565b6115c662ffffff198516611c63565b6115d562ffffff198616611c84565b604080516bffffffffffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190a150565b60008161161d600161146d565b5061145b62ffffff198416602e6020611ca5565b600074010000000000000000000000000000000000000000820161166d57505060665473ffffffffffffffffffffffffffffffffffffffff1690565b8161141e565b600081611680600161146d565b5061145b62ffffff19841660266004611be4565b6000816116a1600161146d565b5061145b62ffffff19841660066020611ca5565b6000816116ca62ffffff198216610539611a92565b5061145b836116da856003611b93565b601886901c6bffffffffffffffffffffffff166003611bc5565b60606000806117118460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117368483602001611e63565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806118658382611a6e565b905060286bffffffffffffffffffffffff601883901c16116118c95760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610530565b6118f26118db62ffffff198316612008565b6118ed610b3462ffffff1985166119b6565b61201d565b915061192861190662ffffff198316611979565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6119745760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e207570646174657200000000000000006044820152606401610530565b915091565b600061141e62ffffff198316826004611be4565b600061141e62ffffff198316600480611be4565b600061141e62ffffff19831660086020611ca5565b600061141e60286119d981601886901c6bffffffffffffffffffffffff16612d6d565b62ffffff19851691906000612094565b600054610100900460ff16611a665760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b6106e061210e565b815160009060208401611a8964ffffffffff85168284612194565b95945050505050565b6000611a9e83836121db565b611b8c576000611abd611ab18560d81c90565b64ffffffffff166121fe565b9150506000611ad28464ffffffffff166121fe565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016105309190612d2b565b5090919050565b60006104846002836004811115611bac57611bac612c51565b611bb69190612d84565b62ffffff198516906002611be4565b6000611a8984611bd58186612d6d565b62ffffff198816919085612094565b6000611bf1826020612dc1565b611bfc906008612de4565b60ff16611c0a858585611ca5565b901c949350505050565b600081611c21600261146d565b50611c3562ffffff1984166002600c611be4565b63ffffffff169392505050565b600081611c4f600261146d565b50611c3562ffffff198416600e600c611be4565b600081611c70600261146d565b50611c3562ffffff198416601a600c611be4565b600081611c91600261146d565b50611c3562ffffff1984166026600c611be4565b60008160ff16600003611cba57506000610484565b611cd28460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611ced60ff841685612c39565b1115611d6557611d4c611d0e8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611d348660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166122e8565b60405162461bcd60e51b81526004016105309190612d2b565b60208260ff161115611ddf5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610530565b600882026000611dfd8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611ee05760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610530565b611ee983612356565b611f5b5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610530565b6000611f758460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611f9f8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611fc45760206060fd5b8285848460045afa50611ffe611fda8760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061141e62ffffff19831682602881612094565b60008061202f62ffffff1985166114af565b9050612088816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061060a8184612393565b6000806120af8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506120c8866123af565b846120d38784612c39565b6120dd9190612c39565b11156120f05762ffffff1991505061060a565b6120fa8582612c39565b9050611ffe8364ffffffffff168286612194565b600054610100900460ff1661218b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b6106e0336117e1565b6000806121a18385612c39565b90506040518111156121b1575060005b806000036121c65762ffffff19915050610484565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166121ef8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561227157600061221d826008612de4565b60ff1685901c905061222e816123f7565b61ffff16841793508160ff1660101461224957601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612204565b50600f5b60ff8160ff1610156122e257600061228e826008612de4565b60ff1685901c905061229f816123f7565b61ffff16831792508160ff166000146122ba57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612275565b50915091565b606060006122f5866121fe565b9150506000612303866121fe565b9150506000612311866121fe565b915050600061231f866121fe565b915050838383836040516020016123399493929190612e0d565b604051602081830303815290604052945050505050949350505050565b60006123628260d81c90565b64ffffffffff1664ffffffffff0361237c57506000919050565b6000612387836123af565b60405110199392505050565b60008060006123a28585612429565b9150915061121881612497565b60006123c98260181c6bffffffffffffffffffffffff1690565b6123e18360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061240960048360ff16901c612683565b60ff1661ffff919091161760081b61242082612683565b60ff1617919050565b600080825160410361245f5760208301516040840151606085015160001a612453878285856127ca565b94509450505050612490565b8251604003612488576020830151604084015161247d8683836128e2565b935093505050612490565b506000905060025b9250929050565b60008160048111156124ab576124ab612c51565b036124b35750565b60018160048111156124c7576124c7612c51565b036125145760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610530565b600281600481111561252857612528612c51565b036125755760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610530565b600381600481111561258957612589612c51565b036125fc5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610530565b600481600481111561261057612610612c51565b03610c695760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610530565b600060f08083179060ff8216900361269e5750603092915050565b8060ff1660f1036126b25750603192915050565b8060ff1660f2036126c65750603292915050565b8060ff1660f3036126da5750603392915050565b8060ff1660f4036126ee5750603492915050565b8060ff1660f5036127025750603592915050565b8060ff1660f6036127165750603692915050565b8060ff1660f70361272a5750603792915050565b8060ff1660f80361273e5750603892915050565b8060ff1660f9036127525750603992915050565b8060ff1660fa036127665750606192915050565b8060ff1660fb0361277a5750606292915050565b8060ff1660fc0361278e5750606392915050565b8060ff1660fd036127a25750606492915050565b8060ff1660fe036127b65750606592915050565b8060ff1660ff0361145e5750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561280157506000905060036128d9565b8460ff16601b1415801561281957508460ff16601c14155b1561282a57506000905060046128d9565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561287e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166128d2576000600192509250506128d9565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83168161291860ff86901c601b612c39565b9050612926878288856127ca565b935093505050935093915050565b803563ffffffff8116811461138657600080fd5b60008060006060848603121561295d57600080fd5b61296684612934565b925061297460208501612934565b9150604084013590509250925092565b60006020828403121561299657600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126129dd57600080fd5b813567ffffffffffffffff808211156129f8576129f861299d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612a3e57612a3e61299d565b81604052838152866020858801011115612a5757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806104608587031215612a8e57600080fd5b612a9785612934565b9350602085013567ffffffffffffffff811115612ab357600080fd5b612abf878288016129cc565b935050610440850186811115612ad457600080fd5b9396929550505060409290920191903590565b60008060408385031215612afa57600080fd5b612b0383612934565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610c6957600080fd5b60008060408385031215612b4657600080fd5b612b4f83612934565b91506020830135612b5f81612b11565b809150509250929050565b600060208284031215612b7c57600080fd5b813567ffffffffffffffff811115612b9357600080fd5b61060a848285016129cc565b600060208284031215612bb157600080fd5b813561048481612b11565b600080600060608486031215612bd157600080fd5b612bda84612934565b95602085013595506040909401359392505050565b600060208284031215612c0157600080fd5b61048482612934565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612c4c57612c4c612c0a565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612ca657602081850181015186830182015201612c8a565b81811115612cb8576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612d2060a0830184612c80565b979650505050505050565b6020815260006104846020830184612c80565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612d7f57612d7f612c0a565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612dbc57612dbc612c0a565b500290565b600060ff821660ff841680821015612ddb57612ddb612c0a565b90039392505050565b600060ff821660ff84168160ff0481118215151615612e0557612e05612c0a565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611ffe56fea26469706673582212205d5993c4cf83d07475fa6717cca8cd06d831ccd043b1312968f6776f42cd245664736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106101825760003560e01c8063928bc4b2116100d8578063bfd84d361161008c578063f2fde38b11610066578063f2fde38b146103ee578063f646a51214610401578063ffa1ad741461041457600080fd5b8063bfd84d361461039b578063ccbdf9c9146103ae578063df034cd0146103ce57600080fd5b80639df7d36d116100bd5780639df7d36d1461033f578063b65672d314610352578063b7bc563e1461038857600080fd5b8063928bc4b2146103195780639d54f4191461032c57600080fd5b8063687052751161013a5780638624c35c116101145780638624c35c1461028b5780638d3638f41461029e5780638da5cb5b146102da57600080fd5b8063687052751461022f578063715018a6146102425780637dfdba281461024a57600080fd5b806348639d241161016b57806348639d24146101c65780634f63be3f146101db57806363415514146101ee57600080fd5b8063089d28941461018757806315a046aa146101a3575b600080fd5b61019060fb5481565b6040519081526020015b60405180910390f35b6101b66101b1366004612948565b61042e565b604051901515815260200161019a565b6101d96101d4366004612984565b61048b565b005b6101b66101e9366004612a77565b610498565b6101906101fc366004612ae7565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260029093019052205490565b6101d961023d366004612a77565b610612565b6101d9610679565b610190610258366004612ae7565b63ffffffff91909116600090815260cc6020908152604080832054835260cb825280832093835260019093019052205490565b6101d9610299366004612b33565b6106e2565b6102c57f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019a565b60335473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019a565b6101d9610327366004612b6a565b61085b565b6101d961033a366004612b9f565b610bf9565b6101d961034d366004612bbc565b610c6c565b6102c5610360366004612bef565b63ffffffff908116600090815260cc6020908152604080832054835260cb9091529020541690565b6101d9610396366004612b9f565b610d60565b6101d96103a9366004612bbc565b610e0e565b6066546102f49073ffffffffffffffffffffffffffffffffffffffff1681565b6065546102f49073ffffffffffffffffffffffffffffffffffffffff1681565b6101d96103fc366004612b9f565b610e3f565b6101d961040f366004612b6a565b610f38565b61041c600081565b60405160ff909116815260200161019a565b63ffffffff8316600090815260cc6020908152604080832054835260cb825280832084845260010190915281205480820361046d576000915050610484565b61047d63ffffffff851682612c39565b4210159150505b9392505050565b610493611113565b60fb55565b825160208085019190912063ffffffff8616600090815260cc8352604080822054825260cb9093529182206001815468010000000000000000900460ff1660028111156104e7576104e7612c51565b146105395760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105975760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e65000000000000000000000000006044820152606401610530565b60006105cd83876020806020026040519081016040528092919082602080028082843760009201919091525089915061117a9050565b60008181526001840160205260409020549091501561060257600092835260029190910160205260409091205550600161060a565b600093505050505b949350505050565b61061e84848484610498565b61066a5760405162461bcd60e51b815260206004820152600660248201527f2170726f766500000000000000000000000000000000000000000000000000006044820152606401610530565b6106738361085b565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106e05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b565b60006106ee6001611234565b9050801561072357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61072c8261138b565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556107dd8360ca54600101600081815260cb60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560ca819055919050565b63ffffffff8416600090815260cc6020526040902055801561085657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b600061086682611410565b9050600061087962ffffff198316611424565b9050600061088c62ffffff198316611464565b63ffffffff808216600090815260cc6020908152604080832054835260cb90915290209192507f0000000000000000000000000000000000000000000000000000000000000000166108e362ffffff19851661148e565b63ffffffff16146109365760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e00000000000000000000000000000000000000006044820152606401610530565b600061094762ffffff1986166114af565b60008181526002840160205260409020549091506109648161150c565b6109b05760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f6365737365640000000000000000000000006044820152606401610530565b6109c9846109c362ffffff198816611520565b8361042e565b610a155760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e647300000000000000000000000000006044820152606401610530565b60c95460ff16600114610a6a5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e74000000000000000000000000000000000000000000006044820152606401610530565b60c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610aa9610aa462ffffff198816611541565b611578565b6000828152600284016020526040812060019055610ad4610acf62ffffff198816611610565b611631565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b0262ffffff198a16611673565b610b1162ffffff198b16611694565b600087815260018a016020526040902054610b3f610b3462ffffff198f166116b5565b62ffffff19166116f4565b6040518663ffffffff1660e01b8152600401610b5f959493929190612ceb565b600060405180830381600087803b158015610b7957600080fd5b505af1158015610b8d573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060c980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610c605760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b610c6981611747565b50565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cd35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b63ffffffff808416600090815260cc6020908152604080832054835260cb825280832086845260018101909252909120549091610d16908390869086906117cd16565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dc75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b606680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b63ffffffff808416600090815260cc6020908152604080832054835260cb9091529020610856918490849061122016565b60335473ffffffffffffffffffffffffffffffffffffffff163314610ea65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610530565b73ffffffffffffffffffffffffffffffffffffffff8116610f2f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610530565b610c69816117e1565b6000610f4382611858565b9150506000610f578262ffffff1916611979565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610fd45760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e000000006044820152606401610530565b6000610fe562ffffff19841661198d565b63ffffffff808416600090815260cc6020908152604080832054835260cb90915290208054929350918116908316116110605760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e74207374617465006044820152606401610530565b600061107162ffffff1986166119a1565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada91716110f6610b348a62ffffff19166119b6565b6040516111039190612d2b565b60405180910390a4505050505050565b60665473ffffffffffffffffffffffffffffffffffffffff1633146106e05760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610530565b8260005b602081101561121857600183821c1660008583602081106111a1576111a1612d3e565b60200201519050816001036111e157604080516020810183905290810185905260600160405160208183030381529060405280519060200120935061120e565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b505060010161117e565b509392505050565b600091825260029092016020526040902055565b60008054610100900460ff16156112d1578160ff1660011480156112575750303b155b6112c95760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610530565b506000919050565b60005460ff80841691161061134e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610530565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114085760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b610c606119e9565b600061141e82610539611a6e565b92915050565b60008161143962ffffff198216610539611a92565b5061145b83611449856001611b93565b611454866002611b93565b6001611bc5565b91505b50919050565b60008161147a60015b62ffffff19831690611a92565b5061145b62ffffff19841660026004611be4565b60008161149b600161146d565b5061145b62ffffff198416602a6004611be4565b6000806114ca8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006114f48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b6000811580159061141e5750506001141590565b60008161152d600161146d565b5061145b62ffffff198416604e6004611be4565b60008161155662ffffff198216610539611a92565b5061145b83611566856002611b93565b611571866003611b93565b6002611bc5565b7f1dad5ea7bf29006ead0af41296d42c169129acd1ec64b3639ebe94b8c01bfa116115a862ffffff198316611c14565b6115b762ffffff198416611c42565b6115c662ffffff198516611c63565b6115d562ffffff198616611c84565b604080516bffffffffffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190a150565b60008161161d600161146d565b5061145b62ffffff198416602e6020611ca5565b600074010000000000000000000000000000000000000000820161166d57505060665473ffffffffffffffffffffffffffffffffffffffff1690565b8161141e565b600081611680600161146d565b5061145b62ffffff19841660266004611be4565b6000816116a1600161146d565b5061145b62ffffff19841660066020611ca5565b6000816116ca62ffffff198216610539611a92565b5061145b836116da856003611b93565b601886901c6bffffffffffffffffffffffff166003611bc5565b60606000806117118460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117368483602001611e63565b508181016020016040529052919050565b6065805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a910160405180910390a15050565b600091825260019092016020526040902055565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806118658382611a6e565b905060286bffffffffffffffffffffffff601883901c16116118c95760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610530565b6118f26118db62ffffff198316612008565b6118ed610b3462ffffff1985166119b6565b61201d565b915061192861190662ffffff198316611979565b5060655473ffffffffffffffffffffffffffffffffffffffff80851691161490565b6119745760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e207570646174657200000000000000006044820152606401610530565b915091565b600061141e62ffffff198316826004611be4565b600061141e62ffffff198316600480611be4565b600061141e62ffffff19831660086020611ca5565b600061141e60286119d981601886901c6bffffffffffffffffffffffff16612d6d565b62ffffff19851691906000612094565b600054610100900460ff16611a665760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b6106e061210e565b815160009060208401611a8964ffffffffff85168284612194565b95945050505050565b6000611a9e83836121db565b611b8c576000611abd611ab18560d81c90565b64ffffffffff166121fe565b9150506000611ad28464ffffffffff166121fe565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016105309190612d2b565b5090919050565b60006104846002836004811115611bac57611bac612c51565b611bb69190612d84565b62ffffff198516906002611be4565b6000611a8984611bd58186612d6d565b62ffffff198816919085612094565b6000611bf1826020612dc1565b611bfc906008612de4565b60ff16611c0a858585611ca5565b901c949350505050565b600081611c21600261146d565b50611c3562ffffff1984166002600c611be4565b63ffffffff169392505050565b600081611c4f600261146d565b50611c3562ffffff198416600e600c611be4565b600081611c70600261146d565b50611c3562ffffff198416601a600c611be4565b600081611c91600261146d565b50611c3562ffffff1984166026600c611be4565b60008160ff16600003611cba57506000610484565b611cd28460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611ced60ff841685612c39565b1115611d6557611d4c611d0e8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611d348660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166122e8565b60405162461bcd60e51b81526004016105309190612d2b565b60208260ff161115611ddf5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610530565b600882026000611dfd8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611ee05760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610530565b611ee983612356565b611f5b5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610530565b6000611f758460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611f9f8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611fc45760206060fd5b8285848460045afa50611ffe611fda8760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b600061141e62ffffff19831682602881612094565b60008061202f62ffffff1985166114af565b9050612088816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061060a8184612393565b6000806120af8660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506120c8866123af565b846120d38784612c39565b6120dd9190612c39565b11156120f05762ffffff1991505061060a565b6120fa8582612c39565b9050611ffe8364ffffffffff168286612194565b600054610100900460ff1661218b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610530565b6106e0336117e1565b6000806121a18385612c39565b90506040518111156121b1575060005b806000036121c65762ffffff19915050610484565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166121ef8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561227157600061221d826008612de4565b60ff1685901c905061222e816123f7565b61ffff16841793508160ff1660101461224957601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612204565b50600f5b60ff8160ff1610156122e257600061228e826008612de4565b60ff1685901c905061229f816123f7565b61ffff16831792508160ff166000146122ba57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612275565b50915091565b606060006122f5866121fe565b9150506000612303866121fe565b9150506000612311866121fe565b915050600061231f866121fe565b915050838383836040516020016123399493929190612e0d565b604051602081830303815290604052945050505050949350505050565b60006123628260d81c90565b64ffffffffff1664ffffffffff0361237c57506000919050565b6000612387836123af565b60405110199392505050565b60008060006123a28585612429565b9150915061121881612497565b60006123c98260181c6bffffffffffffffffffffffff1690565b6123e18360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061240960048360ff16901c612683565b60ff1661ffff919091161760081b61242082612683565b60ff1617919050565b600080825160410361245f5760208301516040840151606085015160001a612453878285856127ca565b94509450505050612490565b8251604003612488576020830151604084015161247d8683836128e2565b935093505050612490565b506000905060025b9250929050565b60008160048111156124ab576124ab612c51565b036124b35750565b60018160048111156124c7576124c7612c51565b036125145760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610530565b600281600481111561252857612528612c51565b036125755760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610530565b600381600481111561258957612589612c51565b036125fc5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610530565b600481600481111561261057612610612c51565b03610c695760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610530565b600060f08083179060ff8216900361269e5750603092915050565b8060ff1660f1036126b25750603192915050565b8060ff1660f2036126c65750603292915050565b8060ff1660f3036126da5750603392915050565b8060ff1660f4036126ee5750603492915050565b8060ff1660f5036127025750603592915050565b8060ff1660f6036127165750603692915050565b8060ff1660f70361272a5750603792915050565b8060ff1660f80361273e5750603892915050565b8060ff1660f9036127525750603992915050565b8060ff1660fa036127665750606192915050565b8060ff1660fb0361277a5750606292915050565b8060ff1660fc0361278e5750606392915050565b8060ff1660fd036127a25750606492915050565b8060ff1660fe036127b65750606592915050565b8060ff1660ff0361145e5750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561280157506000905060036128d9565b8460ff16601b1415801561281957508460ff16601c14155b1561282a57506000905060046128d9565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561287e573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166128d2576000600192509250506128d9565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83168161291860ff86901c601b612c39565b9050612926878288856127ca565b935093505050935093915050565b803563ffffffff8116811461138657600080fd5b60008060006060848603121561295d57600080fd5b61296684612934565b925061297460208501612934565b9150604084013590509250925092565b60006020828403121561299657600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126129dd57600080fd5b813567ffffffffffffffff808211156129f8576129f861299d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612a3e57612a3e61299d565b81604052838152866020858801011115612a5757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806104608587031215612a8e57600080fd5b612a9785612934565b9350602085013567ffffffffffffffff811115612ab357600080fd5b612abf878288016129cc565b935050610440850186811115612ad457600080fd5b9396929550505060409290920191903590565b60008060408385031215612afa57600080fd5b612b0383612934565b946020939093013593505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610c6957600080fd5b60008060408385031215612b4657600080fd5b612b4f83612934565b91506020830135612b5f81612b11565b809150509250929050565b600060208284031215612b7c57600080fd5b813567ffffffffffffffff811115612b9357600080fd5b61060a848285016129cc565b600060208284031215612bb157600080fd5b813561048481612b11565b600080600060608486031215612bd157600080fd5b612bda84612934565b95602085013595506040909401359392505050565b600060208284031215612c0157600080fd5b61048482612934565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612c4c57612c4c612c0a565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612ca657602081850181015186830182015201612c8a565b81811115612cb8576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612d2060a0830184612c80565b979650505050505050565b6020815260006104846020830184612c80565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612d7f57612d7f612c0a565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612dbc57612dbc612c0a565b500290565b600060ff821660ff841680821015612ddb57612ddb612c0a565b90039392505050565b600060ff821660ff84168160ff0481118215151615612e0557612e05612c0a565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611ffe56fea26469706673582212205d5993c4cf83d07475fa6717cca8cd06d831ccd043b1312968f6776f42cd245664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"111560:910:0:-:0;;;111822:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71526:26;;;;111560:910;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;111560:910:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"111560:910:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111661:29;;;;;;;;;160:25:1;;;148:2;133:18;111661:29:0;;;;;;;;107582:361;;;;;;:::i;:::-;;:::i;:::-;;;858:14:1;;851:22;833:41;;821:2;806:18;107582:361:0;693:187:1;111892:118:0;;;;;;:::i;:::-;;:::i;:::-;;108605:1028;;;;;;:::i;:::-;;:::i;102029:230::-;;;;;;:::i;:::-;102196:29;;;;;102154:7;102196:29;;;:14;:29;;;;;;;;;102184:42;;:11;:42;;;;;:68;;;:56;;;;:68;;;;;102029:230;103931:271;;;;;;:::i;:::-;;:::i;72877:84::-;;;:::i;101809:214::-;;;;;;:::i;:::-;101969:29;;;;;101927:7;101969:29;;;:14;:29;;;;;;;;;101957:42;;:11;:42;;;;;:59;;;:52;;;;:59;;;;;101809:214;101334:255;;;;;;:::i;:::-;;:::i;70324:35::-;;;;;;;;3751:10:1;3739:23;;;3721:42;;3709:2;3694:18;70324:35:0;3577:192:1;68421:85:0;68493:6;;;;68421:85;;;3950:42:1;3938:55;;;3920:74;;3908:2;3893:18;68421:85:0;3774:226:1;104640:1415:0;;;;;;:::i;:::-;;:::i;106346:95::-;;;;;;:::i;:::-;;:::i;106792:423::-;;;;;;:::i;:::-;;:::i;101650:153::-;;;;;;:::i;:::-;101760:29;;;;101723:6;101760:29;;;:14;:29;;;;;;;;;101748:42;;:11;:42;;;;;:48;;;101650:153;72075:133;;;;;;:::i;:::-;;:::i;112016:225::-;;;;;;:::i;:::-;;:::i;70479:39::-;;;;;;;;;70450:22;;;;;;;;;69303:198;;;;;;:::i;:::-;;:::i;102749:731::-;;;;;;:::i;:::-;;:::i;80457:33::-;;80489:1;80457:33;;;;;6122:4:1;6110:17;;;6092:36;;6080:2;6065:18;80457:33:0;5950:184:1;107582:361:0;107765:29;;;107721:4;107765:29;;;:14;:29;;;;;;;;;107753:42;;:11;:42;;;;;:59;;;:52;;:59;;;;;;107826:10;;;107822:53;;107859:5;107852:12;;;;;107822:53;107910:26;;;;:5;:26;:::i;:::-;107891:15;:45;;107884:52;;;107582:361;;;;;;:::o;111892:118::-;71972:24;:22;:24::i;:::-;111977:14:::1;:26:::0;111892:118::o;108605:1028::-;108796:19;;;;;;;;;;108874:29;;;108764:4;108874:29;;;:14;:29;;;;;;;108862:42;;:11;:42;;;;;;108981:31;108963:14;;;;;;;:49;;;;;;;;:::i;:::-;;108955:80;;;;-1:-1:-1;;;108955:80:0;;6852:2:1;108955:80:0;;;6834:21:1;6891:2;6871:18;;;6864:30;6930:20;6910:18;;;6903:48;6968:18;;108955:80:0;;;;;;;;;81556:1;109130:28;;;:21;;;:28;;;;;;:62;109109:128;;;;-1:-1:-1;;;109109:128:0;;7199:2:1;109109:128:0;;;7181:21:1;7238:2;7218:18;;;7211:30;7277:21;7257:18;;;7250:49;7316:18;;109109:128:0;6997:343:1;109109:128:0;109305:23;109331:43;109352:5;109359:6;109331:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109367:6:0;;-1:-1:-1;109331:20:0;;-1:-1:-1;109331:43:0:i;:::-;109466:34;;;;:17;;;:34;;;;;;109305:69;;-1:-1:-1;109466:39:0;109462:143;;83129:35;;;;:21;;;;;:35;;;;;;:45;-1:-1:-1;109590:4:0;109583:11;;109462:143;109621:5;109614:12;;;;;108605:1028;;;;;;;:::o;103931:271::-;104111:46;104117:13;104132:8;104142:6;104150;104111:5;:46::i;:::-;104103:65;;;;-1:-1:-1;;;104103:65:0;;7547:2:1;104103:65:0;;;7529:21:1;7586:1;7566:18;;;7559:29;7624:8;7604:18;;;7597:36;7650:18;;104103:65:0;7345:329:1;104103:65:0;104178:17;104186:8;104178:7;:17::i;:::-;103931:271;;;;:::o;72877:84::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7881:2:1;68625:68:0;;;7863:21:1;;;7900:18;;;7893:30;7959:34;7939:18;;;7932:62;8011:18;;68625:68:0;7679:356:1;68625:68:0;72877:84::o;101334:255::-;61317:19;61339:25;61362:1;61339:22;:25::i;:::-;61317:47;;61378:14;61374:65;;;61408:13;:20;;;;;;;;61374:65;101423:34:::1;101448:8;101423:24;:34::i;:::-;101500:7;:11:::0;;;::::1;101510:1;101500:11;::::0;;101553:29:::1;101568:13:::0;109922:12;;109937:1;109922:16;109756:20;109958:25;;;:11;:25;;;;;82601:36;;;;;;;82647:37;;;;;;;;;;;110021:12;:27;;;110036:12;109692:363;-1:-1:-1;109692:363:0;101553:29:::1;101521;::::0;::::1;;::::0;;;:14:::1;:29;::::0;;;;:61;61459:99;;;;61509:5;61493:21;;;;;;61533:14;;-1:-1:-1;6092:36:1;;61533:14:0;;6080:2:1;6065:18;61533:14:0;;;;;;;61459:99;61307:257;101334:255;;:::o;104640:1415::-;104697:10;104710:22;:8;:20;:22::i;:::-;104697:35;-1:-1:-1;104742:15:0;104760:11;-1:-1:-1;;104760:9:0;;;:11::i;:::-;104742:29;-1:-1:-1;104781:20:0;104804:16;-1:-1:-1;;104804:14:0;;;:16::i;:::-;104879:29;;;;104830:34;104879:29;;;:14;:29;;;;;;;;;104867:42;;:11;:42;;;;;104781:39;;-1:-1:-1;105004:11:0;104979:36;:21;-1:-1:-1;;104979:19:0;;;:21::i;:::-;:36;;;104971:61;;;;-1:-1:-1;;;104971:61:0;;8441:2:1;104971:61:0;;;8423:21:1;8480:2;8460:18;;;8453:30;8519:14;8499:18;;;8492:42;8551:18;;104971:61:0;8239:336:1;104971:61:0;105084:20;105107:11;-1:-1:-1;;105107:9:0;;;:11::i;:::-;105128:13;105144:35;;;:21;;;:35;;;;;;105084:34;;-1:-1:-1;105197:33:0;105144:35;105197:26;:33::i;:::-;105189:66;;;;-1:-1:-1;;;105189:66:0;;8782:2:1;105189:66:0;;;8764:21:1;8821:2;8801:18;;;8794:30;8860:22;8840:18;;;8833:50;8900:18;;105189:66:0;8580:344:1;105189:66:0;105286:65;105301:13;105316:27;-1:-1:-1;;105316:25:0;;;:27::i;:::-;105345:5;105286:14;:65::i;:::-;105265:130;;;;-1:-1:-1;;;105265:130:0;;9131:2:1;105265:130:0;;;9113:21:1;9170:2;9150:18;;;9143:30;9209:20;9189:18;;;9182:48;9247:18;;105265:130:0;8929:342:1;105265:130:0;105448:7;;;;;:12;105440:35;;;;-1:-1:-1;;;105440:35:0;;9478:2:1;105440:35:0;;;9460:21:1;9517:2;9497:18;;;9490:30;9556:12;9536:18;;;9529:40;9586:18;;105440:35:0;9276:334:1;105440:35:0;105485:7;:11;;;;;;105506:21;105517:9;-1:-1:-1;;105517:7:0;;;:9::i;:::-;105506:10;:21::i;:::-;83129:35;;;;:21;;;:35;;;;;81631:1;83129:45;;105688:43;105711:19;-1:-1:-1;;105711:17:0;;;:19::i;:::-;105688:22;:43::i;:::-;105668:63;-1:-1:-1;105741:35:0;;;;105790:13;105817:15;-1:-1:-1;;105817:13:0;;;:15::i;:::-;105846:16;-1:-1:-1;;105846:14:0;;;:16::i;:::-;105876:24;;;;:17;;;:24;;;;;;105914:17;:9;-1:-1:-1;;105914:7:0;;;:9::i;:::-;-1:-1:-1;;105914:15:0;;:17::i;:::-;105741:200;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;105956:36:0;;105979:12;;-1:-1:-1;105956:36:0;;;;-1:-1:-1;105956:36:0;;;;;-1:-1:-1;;106037:7:0;:11;;;;106047:1;106037:11;;;-1:-1:-1;;;;;;104640:1415:0:o;106346:95::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7881:2:1;68625:68:0;;;7863:21:1;;;7900:18;;;7893:30;7959:34;7939:18;;;7932:62;8011:18;;68625:68:0;7679:356:1;68625:68:0;106413:21:::1;106425:8;106413:11;:21::i;:::-;106346:95:::0;:::o;106792:423::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7881:2:1;68625:68:0;;;7863:21:1;;;7900:18;;;7893:30;7959:34;7939:18;;;7932:62;8011:18;;68625:68:0;7679:356:1;68625:68:0;106982:29:::1;::::0;;::::1;106933:34;106982:29:::0;;;:14:::1;:29;::::0;;;;;;;;106970:42;;:11:::1;:42:::0;;;;;107051:24;;;:17:::1;::::0;::::1;:24:::0;;;;;;;106970:42;;107085:39:::1;::::0;106970:42;;107069:5;;107113:10;;107085:20:::1;:39;:::i;:::-;107139:69;::::0;;10876:25:1;;;10932:2;10917:18;;10910:34;;;107170:5:0;;107139:69:::1;::::0;::::1;::::0;::::1;::::0;10849:18:1;107139:69:0::1;;;;;;;106923:292;;106792:423:::0;;;:::o;72075:133::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7881:2:1;68625:68:0;;;7863:21:1;;;7900:18;;;7893:30;7959:34;7939:18;;;7932:62;8011:18;;68625:68:0;7679:356:1;68625:68:0;72167:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;72075:133::o;112016:225::-;112164:29;;;;112152:42;112164:29;;;:14;:29;;;;;;;;;112152:42;;:11;:42;;;;;:82;;112212:12;;112226:7;;112152:59;:82;:::i;69303:198::-;68493:6;;68633:23;68493:6;67421:10;68633:23;68625:68;;;;-1:-1:-1;;;68625:68:0;;7881:2:1;68625:68:0;;;7863:21:1;;;7900:18;;;7893:30;7959:34;7939:18;;;7932:62;8011:18;;68625:68:0;7679:356:1;68625:68:0;69391:22:::1;::::0;::::1;69383:73;;;::::0;-1:-1:-1;;;69383:73:0;;11157:2:1;69383:73:0::1;::::0;::::1;11139:21:1::0;11196:2;11176:18;;;11169:30;11235:34;11215:18;;;11208:62;11306:8;11286:18;;;11279:36;11332:19;;69383:73:0::1;10955:402:1::0;69383:73:0::1;69466:28;69485:8;69466:18;:28::i;102749:731::-:0;102825:13;102842:31;102860:12;102842:17;:31::i;:::-;102822:51;;;102883:19;102905:25;:5;:23;;;;:25::i;:::-;102883:47;;102964:11;102948:27;;:12;:27;;;102940:68;;;;-1:-1:-1;;;102940:68:0;;11564:2:1;102940:68:0;;;11546:21:1;11603:2;11583:18;;;11576:30;11642;11622:18;;;11615:58;11690:18;;102940:68:0;11362:352:1;102940:68:0;103018:12;103033:24;-1:-1:-1;;103033:22:0;;;:24::i;:::-;103116:28;;;;103067:34;103116:28;;;:14;:28;;;;;;;;;103104:41;;:11;:41;;;;;103171:13;;103018:39;;-1:-1:-1;103104:41:0;103171:13;;103163:21;;;;103155:65;;;;-1:-1:-1;;;103155:65:0;;11921:2:1;103155:65:0;;;11903:21:1;11960:2;11940:18;;;11933:30;11999:33;11979:18;;;11972:61;12050:18;;103155:65:0;11719:355:1;103155:65:0;103230:15;103248:23;-1:-1:-1;;103248:21:0;;;:23::i;:::-;82940:24;;;;:17;;;:24;;;;;103311:15;82940:37;;103230:41;-1:-1:-1;82774:22:0;;;;;;;;;;103427:7;103420:5;103399:74;;103406:12;103399:74;;;103436:36;:28;:5;:26;;;;:28::i;:36::-;103399:74;;;;;;:::i;:::-;;;;;;;;102812:668;;;;;102749:731;:::o;72267:132::-;72355:15;;;;72333:10;:38;72325:67;;;;-1:-1:-1;;;72325:67:0;;12503:2:1;72325:67:0;;;12485:21:1;12542:2;12522:18;;;12515:30;12581:18;12561;;;12554:46;12617:18;;72325:67:0;12301:340:1;87166:614:0;87345:5;87306:16;87361:413;83559:2;87381:1;:14;87361:413;;;87447:4;87432:11;;;87431:20;87413:15;87481:7;87442:1;87481:10;;;;;;;:::i;:::-;;;;;87465:26;;87509:7;87520:1;87509:12;87505:200;;87562:33;;;;;;12992:19:1;;;13027:12;;;13020:28;;;13064:12;;87562:33:0;;;;;;;;;;;;87552:44;;;;;;87541:55;;87505:200;;;87656:33;;;;;;12992:19:1;;;13027:12;;;13020:28;;;13064:12;;87656:33:0;;;;;;;;;;;;87646:44;;;;;;87635:55;;87505:200;-1:-1:-1;;87746:3:0;;87361:413;;;;87166:614;;;;;:::o;82990:191::-;83129:35;;;;:21;;;;:35;;;;;:45;82990:191::o;63493:808::-;63557:4;63890:13;;;;;;;63886:409;;;63944:7;:12;;63955:1;63944:12;:61;;;;-1:-1:-1;63999:4:0;54747:19;:23;63944:61;63919:166;;;;-1:-1:-1;;;63919:166:0;;13289:2:1;63919:166:0;;;13271:21:1;13328:2;13308:18;;;13301:30;13367:34;13347:18;;;13340:62;13438:16;13418:18;;;13411:44;13472:19;;63919:166:0;13087:410:1;63919:166:0;-1:-1:-1;64106:5:0;;63493:808;-1:-1:-1;63493:808:0:o;63886:409::-;64150:12;;:22;;;;:12;;:22;64142:81;;;;-1:-1:-1;;;64142:81:0;;13289:2:1;64142:81:0;;;13271:21:1;13328:2;13308:18;;;13301:30;13367:34;13347:18;;;13340:62;13438:16;13418:18;;;13411:44;13472:19;;64142:81:0;13087:410:1;64142:81:0;-1:-1:-1;64237:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;63493:808:0:o;63886:409::-;63493:808;;;:::o;71611:142::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;13704:2:1;62896:69:0;;;13686:21:1;13743:2;13723:18;;;13716:30;13782:34;13762:18;;;13755:62;13853:13;13833:18;;;13826:41;13884:19;;62896:69:0;13502:407:1;62896:69:0;71699:16:::1;:14;:16::i;37137:126::-:0;37204:7;37230:26;:8;34725:4;37230:12;:26::i;:::-;37223:33;37137:126;-1:-1:-1;;37137:126:0:o;37387:305::-;37466:7;37447:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;37504:181:::1;37530:8;37556:35;37568:8;37578:12;37556:11;:35::i;:::-;37609:33;37621:8;37631:10;37609:11;:33::i;:::-;34781:12;37504:8;:181::i;:::-;37485:200;;35009:1;37387:305:::0;;;;:::o;40989:151::-;41065:6;41047:7;40069:37;34781:12;34774:20;-1:-1:-1;;40069:16:0;;;;:37::i;:::-;-1:-1:-1;41097:35:0::1;-1:-1:-1::0;;41097:17:0;::::1;39748:1;41130;41097:17;:35::i;41590:161::-:0;41671:6;41653:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41703:40:0::1;-1:-1:-1::0;;41703:17:0;::::1;39900:2;41741:1;41703:17;:40::i;23211:290::-:0;23267:14;23293:12;23308;23312:7;16142:3;16138:17;3426:26;16134:29;;15815:364;23308:12;23293:27;;;;23330:12;23345;23349:7;17248:2;17244:16;3426:26;17240:28;;17002:282;23345:12;23330:27;;23464:21;;;;23211:290;-1:-1:-1;;;23211:290:0:o;83310:182::-;83381:4;83404:36;;;;;:81;;-1:-1:-1;;81631:1:0;83444:41;;;83310:182::o;42028:174::-;42115:6;42097:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;42147:47:0::1;-1:-1:-1::0;;42147:17:0;::::1;40015:2;42192:1;42147:17;:47::i;37814:299::-:0;37891:7;37872:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;37929:177:::1;37955:8;37981:33;37993:8;38003:10;37981:11;:33::i;:::-;38032;38044:8;38054:10;38032:11;:33::i;:::-;34844:10;37504:8;:181::i;112247:221::-:0;112315:146;112336:18;-1:-1:-1;;112336:16:0;;;:18::i;:::-;112368;-1:-1:-1;;112368:16:0;;;:18::i;:::-;112400:17;-1:-1:-1;;112400:15:0;;;:17::i;:::-;112431:20;-1:-1:-1;;112431:18:0;;;:20::i;:::-;112315:146;;;14147:26:1;14200:15;;;14182:34;;14252:15;;;14247:2;14232:18;;14225:43;14304:15;;;14284:18;;;14277:43;14356:15;;;14351:2;14336:18;;14329:43;112315:146:0;;;;;;14124:3:1;112315:146:0;;;112247:221;:::o;41817:147::-;41896:7;41878;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41922:35:0::1;-1:-1:-1::0;;41922:13:0;::::1;39953:2;41954;41922:13;:35::i;110792:643::-:0;110867:17;110969:41;;;110965:464;;-1:-1:-1;;111272:15:0;;;;;63493:808::o;110965:464::-;111407:10;111380:38;34011:127;41384:149;41459:6;41441:7;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41491:34:0::1;-1:-1:-1::0;;41491:17:0;::::1;39845:2;41523:1;41491:17;:34::i;41192:141::-:0;41268:7;41250;40069:37;34781:12;34774:20;;40069:37;-1:-1:-1;41294:32:0::1;-1:-1:-1::0;;41294:13:0;::::1;39797:1;41323:2;41294:13;:32::i;38235:190::-:0;38312:7;38293:8;34969:30;-1:-1:-1;;34969:16:0;;34725:4;34969:16;:30::i;:::-;;38338:80:::1;38347:8;38357:33;38369:8;38379:10;38357:11;:33::i;:::-;17248:2:::0;17244:16;;;3426:26;17240:28;34905:10:::1;37504:8;:181::i;29064:632::-:0;29119:16;29147:11;29168:12;29183;29187:7;17248:2;17244:16;3426:26;17240:28;;17002:282;29183:12;29168:27;;;;29305:4;29299:11;29292:18;;29360:3;29353:10;;29406:33;29419:7;29428:3;29434:4;29428:10;29406:12;:33::i;:::-;-1:-1:-1;29563:14:0;;;29579:4;29559:25;29553:4;29546:39;29626:17;;29064:632;;-1:-1:-1;29064:632:0:o;72505:179::-;72588:7;;;;72605:21;;;;;;;;;;;72641:36;;;72588:7;;;;14618:34:1;;;14683:2;14668:18;;14661:43;;;;72641:36:0;;14530:18:1;72641:36:0;;;;;;;72556:128;72505:179;:::o;82809:175::-;82940:24;;;;:17;;;;:24;;;;;:37;82809:175::o;69655:187::-;69747:6;;;;69763:17;;;;;;;;;;;69795:40;;69747:6;;;69763:17;69747:6;;69795:40;;69728:16;;69795:40;69718:124;69655:187;:::o;78985:474::-;79086:16;;79141:19;:12;79086:16;79141;:19::i;:::-;79133:27;-1:-1:-1;73658:2:0;3426:26;17248:2;17244:16;;;17240:28;74912:37;79170:52;;;;-1:-1:-1;;;79170:52:0;;14917:2:1;79170:52:0;;;14899:21:1;14956:2;14936:18;;;14929:30;14995:20;14975:18;;;14968:48;15033:18;;79170:52:0;14715:342:1;79170:52:0;79243:115;79275:23;-1:-1:-1;;79275:21:0;;;:23::i;:::-;79312:36;:28;-1:-1:-1;;79312:26:0;;;:28::i;:36::-;79243:18;:115::i;:::-;79232:126;-1:-1:-1;79376:47:0;79387:25;-1:-1:-1;;79387:23:0;;;:25::i;:::-;-1:-1:-1;110667:7:0;;;110655:19;;;110667:7;;110655:19;;110554:127;79376:47;79368:84;;;;-1:-1:-1;;;79368:84:0;;15264:2:1;79368:84:0;;;15246:21:1;15303:2;15283:18;;;15276:30;15342:26;15322:18;;;15315:54;15386:18;;79368:84:0;15062:348:1;79368:84:0;78985:474;;;:::o;75053:143::-;75118:6;75150:38;-1:-1:-1;;75150:15:0;;75118:6;75186:1;75150:15;:38::i;75310:136::-;75374:6;75406:32;-1:-1:-1;;75406:15:0;;73552:1;;75406:15;:32::i;75539:124::-;75602:7;75628:28;-1:-1:-1;;75628:11:0;;73599:1;75653:2;75628:11;:28::i;76007:172::-;76075:7;76101:71;73658:2;76131:37;73658:2;17248;17244:16;;;3426:26;17240:28;76131:37;:::i;:::-;-1:-1:-1;;76101:11:0;;;:71;76170:1;76101:11;:71::i;68133:95::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;13704:2:1;62896:69:0;;;13686:21:1;13743:2;13723:18;;;13716:30;13782:34;13762:18;;;13755:62;13853:13;13833:18;;;13826:41;13884:19;;62896:69:0;13502:407:1;62896:69:0;68195:26:::1;:24;:26::i;14411:359::-:0;14515:10;;14481:7;;14662:4;14653:14;;14737:26;;;;14653:14;14515:10;14737:5;:26::i;:::-;14730:33;14411:359;-1:-1:-1;;;;;14411:359:0:o;10829:578::-;10907:7;10931:26;10938:7;10947:9;10931:6;:26::i;:::-;10926:451;;10976:9;10989:35;11007:15;11014:7;15173:3;15169:17;;14962:268;11007:15;10999:24;;10989:9;:35::i;:::-;10973:51;;;11041:9;11054:29;11072:9;11064:18;;11054:9;:29::i;:::-;11141:186;;15912:31:1;11141:186:0;;;15900:44:1;15963:66;16067:3;16063:16;;;16059:25;;16045:12;;;16038:47;16115:15;16101:12;;;16094:37;16165:16;;;16161:25;16147:12;;;16140:47;11038:45:0;;-1:-1:-1;11097:17:0;;-1:-1:-1;16203:12:1;;11141:186:0;;;;;;;;;;;;11097:244;;11362:3;11355:11;;-1:-1:-1;;;11355:11:0;;;;;;;;:::i;10926:451::-;-1:-1:-1;11393:7:0;;10829:578;-1:-1:-1;10829:578:0:o;38947:164::-;39021:7;39047:57;35651:1;39074:5;39066:14;;;;;;;;:::i;:::-;:26;;;;:::i;:::-;-1:-1:-1;;39047:18:0;;;35651:1;39047:18;:57::i;38662:218::-;38803:7;38829:44;38844:5;38851:11;38844:5;38851:3;:11;:::i;:::-;-1:-1:-1;;38829:14:0;;;:44;38864:8;38829:14;:44::i;21877:221::-;21996:14;22074:11;22079:6;22074:2;:11;:::i;:::-;22073:17;;22089:1;22073:17;:::i;:::-;22029:62;;22037:30;22043:7;22052:6;22060;22037:5;:30::i;:::-;22029:62;;;21877:221;-1:-1:-1;;;;21877:221:0:o;93584:149::-;93658:6;93642:5;92230:35;34844:10;34837:18;;92230:35;-1:-1:-1;93690:35:0::1;-1:-1:-1::0;;93690:15:0;::::1;92025:1;93722:2;93690:15;:35::i;:::-;93676:50;;::::0;93584:149;-1:-1:-1;;;93584:149:0:o;93780:::-;93854:6;93838:5;92230:35;34844:10;34837:18;;92230:35;-1:-1:-1;93886:35:0::1;-1:-1:-1::0;;93886:15:0;::::1;92075:2;93918;93886:15;:35::i;93975:147::-:0;94048:6;94032:5;92230:35;34844:10;34837:18;;92230:35;-1:-1:-1;94080:34:0::1;-1:-1:-1::0;;94080:15:0;::::1;92125:2;94111;94080:15;:34::i;94171:153::-:0;94247:6;94231:5;92230:35;34844:10;34837:18;;92230:35;-1:-1:-1;94279:37:0::1;-1:-1:-1::0;;94279:15:0;::::1;92178:2;94313;94279:15;:37::i;20760:771::-:0;20875:14;20905:6;:11;;20915:1;20905:11;20901:59;;-1:-1:-1;20947:1:0;20932:17;;20901:59;20991:12;20995:7;17248:2;17244:16;3426:26;17240:28;;17002:282;20991:12;20973:30;;:15;;;;:6;:15;:::i;:::-;:30;20969:137;;;21026:68;21042:12;21046:7;16142:3;16138:17;3426:26;16134:29;;15815:364;21042:12;21026:68;;21056:12;21060:7;17248:2;17244:16;3426:26;17240:28;;17002:282;21056:12;21026:68;;21070:6;21086;21078:15;;21026;:68::i;:::-;21019:76;;-1:-1:-1;;;21019:76:0;;;;;;;;:::i;20969:137::-;21133:2;21123:6;:12;;;;21115:83;;;;-1:-1:-1;;;21115:83:0;;17328:2:1;21115:83:0;;;17310:21:1;17367:2;17347:18;;;17340:30;17406:34;17386:18;;;17379:62;17477:28;17457:18;;;17450:56;17523:19;;21115:83:0;17126:422:1;21115:83:0;21279:1;21270:10;;21209:15;21315:12;21319:7;16142:3;16138:17;3426:26;16134:29;;15815:364;21315:12;21300:27;;;-1:-1:-1;21337:13:0;8244:66;8214:12;;;8193:131;21489:17;;;;21483:24;21479:36;;;-1:-1:-1;;;;;20760:771:0:o;27792:902::-;27870:15;-1:-1:-1;;8728:15:0;;;;27897:69;;;;-1:-1:-1;;;27897:69:0;;17755:2:1;27897:69:0;;;17737:21:1;17794:2;17774:18;;;17767:30;17833:34;17813:18;;;17806:62;17904:10;17884:18;;;17877:38;17932:19;;27897:69:0;17553:404:1;27897:69:0;27984:16;27992:7;27984;:16::i;:::-;27976:72;;;;-1:-1:-1;;;27976:72:0;;18164:2:1;27976:72:0;;;18146:21:1;18203:2;18183:18;;;18176:30;18242:34;18222:18;;;18215:62;18313:13;18293:18;;;18286:41;18344:19;;27976:72:0;17962:407:1;27976:72:0;28058:12;28073;28077:7;17248:2;17244:16;3426:26;17240:28;;17002:282;28073:12;28058:27;;;;28095:15;28113:12;28117:7;16142:3;16138:17;3426:26;16134:29;;15815:364;28113:12;28095:30;;;;28136:11;28257:4;28251:11;28244:18;;28344:7;28339:3;28336:16;28333:94;;;28384:4;28378;28371:18;28333:94;28599:4;28590:7;28584:4;28575:7;28572:1;28565:5;28554:50;28550:55;28635:52;28656:15;28663:7;15173:3;15169:17;;14962:268;28656:15;12817:27;12821:2;12817:27;;;;12891:17;;12883:26;;12955:17;;12951:2;12947:26;;12567:446;28635:52;28625:62;27792:902;-1:-1:-1;;;;;;27792:902:0:o;75769:155::-;75832:7;75858:59;-1:-1:-1;;75858:11:0;;75832:7;73658:2;75832:7;75858:11;:59::i;76506:285::-;76616:14;;76663;-1:-1:-1;;76663:12:0;;;:14::i;:::-;76646:31;;76696:36;76725:6;52241:58;;20131:66:1;52241:58:0;;;20119:79:1;20214:12;;;20207:28;;;52111:7:0;;20251:12:1;;52241:58:0;;;;;;;;;;;;52231:69;;;;;;52224:76;;52042:265;;;;76696:36;76687:45;;76751:33;76765:6;76773:10;76751:13;:33::i;17885:399::-;18024:7;18043:12;18058;18062:7;16142:3;16138:17;3426:26;16134:29;;15815:364;18058:12;18043:27;;;;18154:12;18158:7;18154:3;:12::i;:::-;18147:4;18131:13;18138:6;18131:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;18127:77;;;-1:-1:-1;;18182:11:0;;;;;18127:77;18221:13;18228:6;18221:4;:13;:::i;:::-;18214:20;;18251:26;18257:7;18251:26;;18266:4;18272;18251:5;:26::i;68234:111::-;62904:13;;;;;;;62896:69;;;;-1:-1:-1;;;62896:69:0;;13704:2:1;62896:69:0;;;13686:21:1;13743:2;13723:18;;;13716:30;13782:34;13762:18;;;13755:62;13853:13;13833:18;;;13826:41;13884:19;;62896:69:0;13502:407:1;62896:69:0;68306:32:::1;67421:10:::0;68306:18:::1;:32::i;13552:462::-:0;13663:15;;13705:11;13712:4;13705;:11;:::i;:::-;13690:26;;13831:4;13825:11;13819:4;13816:21;13813:66;;;-1:-1:-1;13864:1:0;13813:66;13902:4;13910:1;13902:9;13898:51;;-1:-1:-1;;13927:11:0;;;;;13898:51;-1:-1:-1;;12821:2:0;12817:27;;;12891:17;;;;12883:26;;;12955:17;12951:2;12947:26;;13552:462::o;10399:132::-;10473:4;10515:9;10496:28;;:15;10503:7;15173:3;15169:17;;14962:268;10496:15;:28;;;;10399:132;-1:-1:-1;;;10399:132:0:o;5787:667::-;5841:13;;5897:2;5882:258;5905:2;5901:1;:6;;;5882:258;;;5925:11;5952:5;:1;5956;5952:5;:::i;:::-;5945:13;;:2;:13;;5925:34;;5982:14;5990:5;5982:7;:14::i;:::-;5973:23;;;;;;6014:1;:7;;6019:2;6014:7;6010:58;;6051:2;6041:12;;;;;6010:58;-1:-1:-1;6109:6:0;;5882:258;;;-1:-1:-1;6203:2:0;6188:260;6211:3;6207:1;:7;;;6188:260;;;6232:11;6259:5;:1;6263;6259:5;:::i;:::-;6252:13;;:2;:13;;6232:34;;6290:14;6298:5;6290:7;:14::i;:::-;6280:24;;;;;;6322:1;:6;;6327:1;6322:6;6318:58;;6359:2;6348:13;;;;;6318:58;-1:-1:-1;6417:6:0;;6188:260;;;;5787:667;;;:::o;19517:741::-;19663:17;19695:9;19708:15;19718:4;19708:9;:15::i;:::-;19692:31;;;19736:9;19749:15;19759:4;19749:9;:15::i;:::-;19733:31;;;19777:9;19790:17;19800:6;19790:9;:17::i;:::-;19774:33;;;19820:9;19833:17;19843:6;19833:9;:17::i;:::-;19817:33;;;20000:1;20062;20142;20204;19886:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19860:391;;19682:576;;;;19517:741;;;;;;:::o;9401:333::-;9458:8;9482:15;9489:7;15173:3;15169:17;;14962:268;9482:15;:31;;9501:12;9482:31;9478:74;;-1:-1:-1;9536:5:0;;9401:333;-1:-1:-1;9401:333:0:o;9478:74::-;9561:12;9576;9580:7;9576:3;:12::i;:::-;9711:4;9705:11;-1:-1:-1;9692:26:0;;9401:333;-1:-1:-1;;;9401:333:0:o;48338:227::-;48416:7;48436:17;48455:18;48477:27;48488:4;48494:9;48477:10;:27::i;:::-;48435:69;;;;48514:18;48526:5;48514:11;:18::i;17458:147::-;17511:7;17576:12;17580:7;17248:2;17244:16;3426:26;17240:28;;17002:282;17576:12;17561;17565:7;16142:3;16138:17;3426:26;16134:29;;15815:364;17561:12;:27;17554:34;;;;17458:147;;;:::o;5264:199::-;5314:14;5351:18;5367:1;5361:2;:7;;;;5351:9;:18::i;:::-;5340:29;;5393:13;;;;;;5405:1;5393:13;5427;5437:2;5427:9;:13::i;:::-;5416:24;;;;5264:199;-1:-1:-1;5264:199:0:o;46273:1279::-;46354:7;46363:12;46584:9;:16;46604:2;46584:22;46580:966;;46873:4;46858:20;;46852:27;46922:4;46907:20;;46901:27;46979:4;46964:20;;46958:27;46622:9;46950:36;47020:25;47031:4;46950:36;46852:27;46901;47020:10;:25::i;:::-;47013:32;;;;;;;;;46580:966;47066:9;:16;47086:2;47066:22;47062:484;;47335:4;47320:20;;47314:27;47385:4;47370:20;;47364:27;47425:23;47436:4;47314:27;47364;47425:10;:23::i;:::-;47418:30;;;;;;;;47062:484;-1:-1:-1;47495:1:0;;-1:-1:-1;47499:35:0;47062:484;46273:1279;;;;;:::o;44578:631::-;44655:20;44646:5;:29;;;;;;;;:::i;:::-;;44642:561;;44578:631;:::o;44642:561::-;44751:29;44742:5;:38;;;;;;;;:::i;:::-;;44738:465;;44796:34;;-1:-1:-1;;;44796:34:0;;20476:2:1;44796:34:0;;;20458:21:1;20515:2;20495:18;;;20488:30;20554:26;20534:18;;;20527:54;20598:18;;44796:34:0;20274:348:1;44738:465:0;44860:35;44851:5;:44;;;;;;;;:::i;:::-;;44847:356;;44911:41;;-1:-1:-1;;;44911:41:0;;20829:2:1;44911:41:0;;;20811:21:1;20868:2;20848:18;;;20841:30;20907:33;20887:18;;;20880:61;20958:18;;44911:41:0;20627:355:1;44847:356:0;44982:30;44973:5;:39;;;;;;;;:::i;:::-;;44969:234;;45028:44;;-1:-1:-1;;;45028:44:0;;21189:2:1;45028:44:0;;;21171:21:1;21228:2;21208:18;;;21201:30;21267:34;21247:18;;;21240:62;21338:4;21318:18;;;21311:32;21360:19;;45028:44:0;20987:398:1;44969:234:0;45102:30;45093:5;:39;;;;;;;;:::i;:::-;;45089:114;;45148:44;;-1:-1:-1;;;45148:44:0;;21592:2:1;45148:44:0;;;21574:21:1;21631:2;21611:18;;;21604:30;21670:34;21650:18;;;21643:62;21741:4;21721:18;;;21714:32;21763:19;;45148:44:0;21390:398:1;3699:1393:0;3751:10;3917:4;3912:9;;;;3963:15;;;;;3959:57;;-1:-1:-1;4001:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;3959:57::-;4034:7;:15;;4045:4;4034:15;4030:57;;-1:-1:-1;4072:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4030:57::-;4105:7;:15;;4116:4;4105:15;4101:57;;-1:-1:-1;4143:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4101:57::-;4176:7;:15;;4187:4;4176:15;4172:57;;-1:-1:-1;4214:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4172:57::-;4247:7;:15;;4258:4;4247:15;4243:57;;-1:-1:-1;4285:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4243:57::-;4318:7;:15;;4329:4;4318:15;4314:57;;-1:-1:-1;4356:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4314:57::-;4389:7;:15;;4400:4;4389:15;4385:57;;-1:-1:-1;4427:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4385:57::-;4460:7;:15;;4471:4;4460:15;4456:57;;-1:-1:-1;4498:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4456:57::-;4531:7;:15;;4542:4;4531:15;4527:57;;-1:-1:-1;4569:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4527:57::-;4602:7;:15;;4613:4;4602:15;4598:57;;-1:-1:-1;4640:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4598:57::-;4673:7;:15;;4684:4;4673:15;4669:57;;-1:-1:-1;4711:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4669:57::-;4744:7;:15;;4755:4;4744:15;4740:57;;-1:-1:-1;4782:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4740:57::-;4815:7;:15;;4826:4;4815:15;4811:57;;-1:-1:-1;4853:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4811:57::-;4886:7;:15;;4897:4;4886:15;4882:57;;-1:-1:-1;4924:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4882:57::-;4957:7;:15;;4968:4;4957:15;4953:57;;-1:-1:-1;4995:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;4953:57::-;5028:7;:15;;5039:4;5028:15;5024:57;;-1:-1:-1;5066:4:0;;3699:1393;-1:-1:-1;;3699:1393:0:o;49746:1603::-;49872:7;;50796:66;50783:79;;50779:161;;;-1:-1:-1;50894:1:0;;-1:-1:-1;50898:30:0;50878:51;;50779:161;50953:1;:7;;50958:2;50953:7;;:18;;;;;50964:1;:7;;50969:2;50964:7;;50953:18;50949:100;;;-1:-1:-1;51003:1:0;;-1:-1:-1;51007:30:0;50987:51;;50949:100;51160:24;;;51143:14;51160:24;;;;;;;;;22020:25:1;;;22093:4;22081:17;;22061:18;;;22054:45;;;;22115:18;;;22108:34;;;22158:18;;;22151:34;;;51160:24:0;;21992:19:1;;51160:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51160:24:0;;;;;;-1:-1:-1;;51198:20:0;;;51194:101;;51250:1;51254:29;51234:50;;;;;;;51194:101;51313:6;-1:-1:-1;51321:20:0;;-1:-1:-1;49746:1603:0;;;;;;;;:::o;48819:336::-;48929:7;;48987:66;48974:80;;48929:7;49080:25;49096:3;49081:18;;;49103:2;49080:25;:::i;:::-;49064:42;;49123:25;49134:4;49140:1;49143;49146;49123:10;:25::i;:::-;49116:32;;;;;;48819:336;;;;;;:::o;196:163:1:-;263:20;;323:10;312:22;;302:33;;292:61;;349:1;346;339:12;364:324;439:6;447;455;508:2;496:9;487:7;483:23;479:32;476:52;;;524:1;521;514:12;476:52;547:28;565:9;547:28;:::i;:::-;537:38;;594:37;627:2;616:9;612:18;594:37;:::i;:::-;584:47;;678:2;667:9;663:18;650:32;640:42;;364:324;;;;;:::o;885:180::-;944:6;997:2;985:9;976:7;972:23;968:32;965:52;;;1013:1;1010;1003:12;965:52;-1:-1:-1;1036:23:1;;885:180;-1:-1:-1;885:180:1:o;1070:184::-;1122:77;1119:1;1112:88;1219:4;1216:1;1209:15;1243:4;1240:1;1233:15;1259:777;1301:5;1354:3;1347:4;1339:6;1335:17;1331:27;1321:55;;1372:1;1369;1362:12;1321:55;1408:6;1395:20;1434:18;1471:2;1467;1464:10;1461:36;;;1477:18;;:::i;:::-;1611:2;1605:9;1673:4;1665:13;;1516:66;1661:22;;;1685:2;1657:31;1653:40;1641:53;;;1709:18;;;1729:22;;;1706:46;1703:72;;;1755:18;;:::i;:::-;1795:10;1791:2;1784:22;1830:2;1822:6;1815:18;1876:3;1869:4;1864:2;1856:6;1852:15;1848:26;1845:35;1842:55;;;1893:1;1890;1883:12;1842:55;1957:2;1950:4;1942:6;1938:17;1931:4;1923:6;1919:17;1906:54;2004:1;1997:4;1992:2;1984:6;1980:15;1976:26;1969:37;2024:6;2015:15;;;;;;1259:777;;;;:::o;2041:609::-;2161:6;2169;2177;2185;2238:4;2226:9;2217:7;2213:23;2209:34;2206:54;;;2256:1;2253;2246:12;2206:54;2279:28;2297:9;2279:28;:::i;:::-;2269:38;;2358:2;2347:9;2343:18;2330:32;2385:18;2377:6;2374:30;2371:50;;;2417:1;2414;2407:12;2371:50;2440:49;2481:7;2472:6;2461:9;2457:22;2440:49;:::i;:::-;2430:59;;;2523:4;2512:9;2508:20;2547:7;2543:2;2540:15;2537:35;;;2568:1;2565;2558:12;2537:35;2041:609;;;;-1:-1:-1;;;2606:2:1;2591:18;;;;;2628:16;;;2041:609::o;2655:252::-;2722:6;2730;2783:2;2771:9;2762:7;2758:23;2754:32;2751:52;;;2799:1;2796;2789:12;2751:52;2822:28;2840:9;2822:28;:::i;:::-;2812:38;2897:2;2882:18;;;;2869:32;;-1:-1:-1;;;2655:252:1:o;3094:154::-;3180:42;3173:5;3169:54;3162:5;3159:65;3149:93;;3238:1;3235;3228:12;3253:319;3320:6;3328;3381:2;3369:9;3360:7;3356:23;3352:32;3349:52;;;3397:1;3394;3387:12;3349:52;3420:28;3438:9;3420:28;:::i;:::-;3410:38;;3498:2;3487:9;3483:18;3470:32;3511:31;3536:5;3511:31;:::i;:::-;3561:5;3551:15;;;3253:319;;;;;:::o;4005:320::-;4073:6;4126:2;4114:9;4105:7;4101:23;4097:32;4094:52;;;4142:1;4139;4132:12;4094:52;4182:9;4169:23;4215:18;4207:6;4204:30;4201:50;;;4247:1;4244;4237:12;4201:50;4270:49;4311:7;4302:6;4291:9;4287:22;4270:49;:::i;4330:247::-;4389:6;4442:2;4430:9;4421:7;4417:23;4413:32;4410:52;;;4458:1;4455;4448:12;4410:52;4497:9;4484:23;4516:31;4541:5;4516:31;:::i;4582:320::-;4658:6;4666;4674;4727:2;4715:9;4706:7;4702:23;4698:32;4695:52;;;4743:1;4740;4733:12;4695:52;4766:28;4784:9;4766:28;:::i;:::-;4756:38;4841:2;4826:18;;4813:32;;-1:-1:-1;4892:2:1;4877:18;;;4864:32;;4582:320;-1:-1:-1;;;4582:320:1:o;4907:184::-;4965:6;5018:2;5006:9;4997:7;4993:23;4989:32;4986:52;;;5034:1;5031;5024:12;4986:52;5057:28;5075:9;5057:28;:::i;6139:184::-;6191:77;6188:1;6181:88;6288:4;6285:1;6278:15;6312:4;6309:1;6302:15;6328:128;6368:3;6399:1;6395:6;6392:1;6389:13;6386:39;;;6405:18;;:::i;:::-;-1:-1:-1;6441:9:1;;6328:128::o;6461:184::-;6513:77;6510:1;6503:88;6610:4;6607:1;6600:15;6634:4;6631:1;6624:15;9615:530;9656:3;9694:5;9688:12;9721:6;9716:3;9709:19;9746:1;9756:162;9770:6;9767:1;9764:13;9756:162;;;9832:4;9888:13;;;9884:22;;9878:29;9860:11;;;9856:20;;9849:59;9785:12;9756:162;;;9936:6;9933:1;9930:13;9927:87;;;10002:1;9995:4;9986:6;9981:3;9977:16;9973:27;9966:38;9927:87;-1:-1:-1;10059:2:1;10047:15;10064:66;10043:88;10034:98;;;;10134:4;10030:109;;9615:530;-1:-1:-1;;9615:530:1:o;10150:547::-;10368:4;10397:10;10446:2;10438:6;10434:15;10423:9;10416:34;10498:2;10490:6;10486:15;10481:2;10470:9;10466:18;10459:43;;10538:6;10533:2;10522:9;10518:18;10511:34;10581:6;10576:2;10565:9;10561:18;10554:34;10625:3;10619;10608:9;10604:19;10597:32;10646:45;10686:3;10675:9;10671:19;10663:6;10646:45;:::i;:::-;10638:53;10150:547;-1:-1:-1;;;;;;;10150:547:1:o;12079:217::-;12226:2;12215:9;12208:21;12189:4;12246:44;12286:2;12275:9;12271:18;12263:6;12246:44;:::i;12646:184::-;12698:77;12695:1;12688:88;12795:4;12792:1;12785:15;12819:4;12816:1;12809:15;15415:125;15455:4;15483:1;15480;15477:8;15474:34;;;15488:18;;:::i;:::-;-1:-1:-1;15525:9:1;;15415:125::o;16450:228::-;16490:7;16616:1;16548:66;16544:74;16541:1;16538:81;16533:1;16526:9;16519:17;16515:105;16512:131;;;16623:18;;:::i;:::-;-1:-1:-1;16663:9:1;;16450:228::o;16683:195::-;16721:4;16758;16755:1;16751:12;16790:4;16787:1;16783:12;16815:3;16810;16807:12;16804:38;;;16822:18;;:::i;:::-;16859:13;;;16683:195;-1:-1:-1;;;16683:195:1:o;16883:238::-;16921:7;16961:4;16958:1;16954:12;16993:4;16990:1;16986:12;17053:3;17047:4;17043:14;17038:3;17035:23;17028:3;17021:11;17014:19;17010:49;17007:75;;;17062:18;;:::i;:::-;17102:13;;16883:238;-1:-1:-1;;;16883:238:1:o;18493:1391::-;19215:34;19203:47;;19280:23;19275:2;19266:12;;19259:45;19323:66;19427:3;19423:16;;;19419:25;;19414:2;19405:12;;19398:47;19464:17;19506:2;19497:12;;19490:24;;;19548:16;;;19544:25;;19539:2;19530:12;;19523:47;19600:34;19595:2;19586:12;;19579:56;19666:3;19660;19651:13;;19644:26;19705:16;;;19701:25;;19695:3;19686:13;;19679:48;19752:3;19743:13;;19736:25;19796:16;;;19792:25;19786:3;19777:13;;19770:48;18451:3;19873;19864:13;;18439:16;-1:-1:-1;18471:11:1;;;19834:44;18374:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"updaterTip","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"relayerTip","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"proverTip","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"processorTip","type":"uint96"}],"name":"LogTips","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"Process","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"previousConfirmAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newConfirmAt","type":"uint256"}],"name":"SetConfirmation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"acceptableRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"activeReplicaConfirmedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_messageId","type":"bytes32"}],"name":"activeReplicaMessageStatus","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"}],"name":"activeReplicaNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"process","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"prove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"proveAndProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sensitiveValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"uint256","name":"_confirmAt","type":"uint256"}],"name":"setConfirmation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_messageHash","type":"bytes32"},{"internalType":"bytes32","name":"_status","type":"bytes32"}],"name":"setMessageStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newValue","type":"uint256"}],"name":"setSensitiveValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"submitAttestation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"Process(uint32,bytes32)":{"notice":"Emitted when message is processed"},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"notice":"Emitted when a root's confirmation is modified by governance"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"}},"kind":"user","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"notice":"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed"},"initialize(uint32,address)":{"notice":"Initialize the replica"},"process(bytes)":{"notice":"Given formatted message, attempts to dispatch message payload to end recipient."},"prove(uint32,bytes,bytes32[32],uint256)":{"notice":"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf."},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"notice":"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message."},"setConfirmation(uint32,bytes32,uint256)":{"notice":"Set confirmAt for a given root"},"setUpdater(address)":{"notice":"Set Updater role"},"submitAttestation(bytes)":{"notice":"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event."}},"version":1},"developerDoc":{"kind":"dev","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"params":{"_root":"the Merkle root, submitted in an update, to check"},"returns":{"_0":"TRUE iff root has been submitted \u0026 timeout has expired"}},"initialize(uint32,address)":{"details":"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer","params":{"_remoteDomain":"The domain of the Home contract this follows","_updater":"The EVM id of the updater"}},"owner()":{"details":"Returns the address of the current owner."},"process(bytes)":{"details":"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.","params":{"_message":"Formatted message"}},"prove(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message","_proof":"Merkle proof of inclusion for leaf"},"returns":{"_0":"Returns true if proof was valid and `prove` call succeeded*"}},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if `prove` call returns false","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message (refer to UpdaterStorage.sol Message library)","_proof":"Merkle proof of inclusion for message's leaf"}},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setConfirmation(uint32,bytes32,uint256)":{"details":"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)","params":{"_confirmAt":"The new confirmation time. Set to 0 to \"delete\" a root.","_root":"The root for which to modify confirm time"}},"setUpdater(address)":{"details":"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)","params":{"_updater":"New Updater"}},"submitAttestation(bytes)":{"details":"Reverts if update doesn't build off latest committedRoot or if signature is invalid.","params":{"_attestation":"Attestation data and signature"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"updaterTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"relayerTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"proverTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"processorTip\",\"type\":\"uint96\"}],\"name\":\"LogTips\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sensitiveValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_status\",\"type\":\"bytes32\"}],\"name\":\"setMessageStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newValue\",\"type\":\"uint256\"}],\"name\":\"setSensitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"params\":{\"_root\":\"the Merkle root, submitted in an update, to check\"},\"returns\":{\"_0\":\"TRUE iff root has been submitted \u0026 timeout has expired\"}},\"initialize(uint32,address)\":{\"details\":\"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer\",\"params\":{\"_remoteDomain\":\"The domain of the Home contract this follows\",\"_updater\":\"The EVM id of the updater\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"process(bytes)\":{\"details\":\"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.\",\"params\":{\"_message\":\"Formatted message\"}},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message\",\"_proof\":\"Merkle proof of inclusion for leaf\"},\"returns\":{\"_0\":\"Returns true if proof was valid and `prove` call succeeded*\"}},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if `prove` call returns false\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message (refer to UpdaterStorage.sol Message library)\",\"_proof\":\"Merkle proof of inclusion for message's leaf\"}},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"details\":\"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)\",\"params\":{\"_confirmAt\":\"The new confirmation time. Set to 0 to \\\"delete\\\" a root.\",\"_root\":\"The root for which to modify confirm time\"}},\"setUpdater(address)\":{\"details\":\"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)\",\"params\":{\"_updater\":\"New Updater\"}},\"submitAttestation(bytes)\":{\"details\":\"Reverts if update doesn't build off latest committedRoot or if signature is invalid.\",\"params\":{\"_attestation\":\"Attestation data and signature\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"Process(uint32,bytes32)\":{\"notice\":\"Emitted when message is processed\"},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"notice\":\"Emitted when a root's confirmation is modified by governance\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"}},\"kind\":\"user\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"notice\":\"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed\"},\"initialize(uint32,address)\":{\"notice\":\"Initialize the replica\"},\"process(bytes)\":{\"notice\":\"Given formatted message, attempts to dispatch message payload to end recipient.\"},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf.\"},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message.\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"notice\":\"Set confirmAt for a given root\"},\"setUpdater(address)\":{\"notice\":\"Set Updater role\"},\"submitAttestation(bytes)\":{\"notice\":\"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ReplicaManagerHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74","acceptableRoot(uint32,uint32,bytes32)":"15a046aa","activeReplicaConfirmedAt(uint32,bytes32)":"7dfdba28","activeReplicaMessageStatus(uint32,bytes32)":"63415514","activeReplicaNonce(uint32)":"b65672d3","initialize(uint32,address)":"8624c35c","localDomain()":"8d3638f4","owner()":"8da5cb5b","process(bytes)":"928bc4b2","prove(uint32,bytes,bytes32[32],uint256)":"4f63be3f","proveAndProcess(uint32,bytes,bytes32[32],uint256)":"68705275","renounceOwnership()":"715018a6","sensitiveValue()":"089d2894","setConfirmation(uint32,bytes32,uint256)":"9df7d36d","setMessageStatus(uint32,bytes32,bytes32)":"bfd84d36","setSensitiveValue(uint256)":"48639d24","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","submitAttestation(bytes)":"f646a512","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/ReplicaManagerHarness.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e4a6b55ccddf986f92f5cfb09714263d2a6202b4b4f72d27ca49ee6f67e97d2f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e4a6b55ccddf986f92f5cfb09714263d2a6202b4b4f72d27ca49ee6f67e97d2f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"42512:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;42512:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"42512:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220aca15275cad43ec21bf17eec94285c35a7f23050128748b1fd7887bd7c10347b64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220aca15275cad43ec21bf17eec94285c35a7f23050128748b1fd7887bd7c10347b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"94517:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;94517:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"94517:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ac88c3547b033099a64782d3089407652a47a25711fa74f8cc63c3f2c89e257764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ac88c3547b033099a64782d3089407652a47a25711fa74f8cc63c3f2c89e257764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"91516:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;91516:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"91516:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206043199bfcbf1d096483744e4852fb3ab18a8af10a931440cec231cd1ffb96d964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206043199bfcbf1d096483744e4852fb3ab18a8af10a931440cec231cd1ffb96d964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33030:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33030:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33030:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122076cea108b33e9e77fb1148c260dc13777ff564aa7a14f6f38bd36ab93a714f3564736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122076cea108b33e9e77fb1148c260dc13777ff564aa7a14f6f38bd36ab93a714f3564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"782:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;782:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"782:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;3295:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;3295:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/ReplicaManagerHarness.sol:UpdaterStorage":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"}},"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"NewUpdater(address,address)":{"params":{"newUpdater":"The address of the new updater","oldUpdater":"The address of the old updater"}},"Update(uint32,uint32,bytes32,bytes)":{"params":{"homeDomain":"Domain of home contract","nonce":"Nonce of new merkle root","root":"New merkle root","signature":"Updater's signature on `homeDomain`, `nonce` and `root`"}}},"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"params\":{\"newUpdater\":\"The address of the new updater\",\"oldUpdater\":\"The address of the old updater\"}},\"Update(uint32,uint32,bytes32,bytes)\":{\"params\":{\"homeDomain\":\"Domain of home contract\",\"nonce\":\"Nonce of new merkle root\",\"root\":\"New merkle root\",\"signature\":\"Updater's signature on `homeDomain`, `nonce` and `root`\"}}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"UpdaterStorage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/ReplicaManagerHarness.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220cec0a89c824cbd4e8679a25b3ced6112eef8940537a0653b72c152453d78715f64736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220cec0a89c824cbd4e8679a25b3ced6112eef8940537a0653b72c152453d78715f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SynapseBase_initialize(_updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit Update(remoteDomain, nonce, newRoot, _view.attestationSignature().clone());\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to UpdaterStorage.sol Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(address _updater) external onlyOwner {\n _setUpdater(_updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _isUpdater(uint32, address _updater) internal view override returns (bool) {\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80433:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"80433:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80457:33;;80489:1;80457:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;80457:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0x86705d65099b4480a1773ff236941037ea9a411c10cd09d7e6cff64efe94648b\",\"urls\":[\"bzz-raw://b19f023277493dce3b4d8140e7ad5c71ee081b77bb710191e431c0c5109d175b\",\"dweb:/ipfs/QmR5WoMo5fAhtJG2fLhq2xVepWB7vzRJ75juBUV75eFpoY\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file +{"solidity/ReplicaManagerHarness.sol:AbstractGuardRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"AbstractGuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:AbstractNotaryRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"AbstractNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d25c14d60f8a9c2700c5a064a16ba5c6887c5014073a19c8ecb828328ac95e0b64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d25c14d60f8a9c2700c5a064a16ba5c6887c5014073a19c8ecb828328ac95e0b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"96689:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;96689:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"96689:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207c0dbe30d886cdc4b151bc64bfdcedad06581277216b34c43a192ab1b618c8eb64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207c0dbe30d886cdc4b151bc64bfdcedad06581277216b34c43a192ab1b618c8eb64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32270:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32270:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32270:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204ac565f954e44279ccec9766349f01578ebcbb872f6ceaf531135398705bea0b64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212204ac565f954e44279ccec9766349f01578ebcbb872f6ceaf531135398705bea0b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"46393:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;46393:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"46393:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c3d9bb4f6efabc99aff44b49f45c704f844c7519adf9d31de8ba78cd5cb8694364736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220c3d9bb4f6efabc99aff44b49f45c704f844c7519adf9d31de8ba78cd5cb8694364736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"37467:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;37467:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"37467:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:EnumerableSet":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e19ec396e6784a3ba231c4b74603e72835301c39327be67face151917bc1274d64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e19ec396e6784a3ba231c4b74603e72835301c39327be67face151917bc1274d64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"52846:11368:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;52846:11368:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"52846:11368:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"EnumerableSet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:GlobalNotaryRegistry":{"code":"0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea26469706673582212202c863d08bbc429683a33ede55c774990b476fb8c04c443ed799eb51db38eac6764736f6c634300080d0033","runtime-code":"0x6080604052600080fdfea26469706673582212202c863d08bbc429683a33ede55c774990b476fb8c04c443ed799eb51db38eac6764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"48125:4371:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"48125:4371:0:-:0;;;;;","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"GlobalNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:GuardRegistry":{"code":"0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220ce6a74d10a941b0e09b176e9e0e31acd9feeb3ce34afeac0aa68470f3be1d27364736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220ce6a74d10a941b0e09b176e9e0e31acd9feeb3ce34afeac0aa68470f3be1d27364736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"64216:3868:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"64216:3868:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66914:95;;;:::i;:::-;;;160:25:1;;;148:2;133:18;66914:95:0;;;;;;;;66801:107;;;;;;:::i;:::-;;:::i;:::-;;;557:42:1;545:55;;;527:74;;515:2;500:18;66801:107:0;381:226:1;66694:101:0;;;:::i;:::-;;;;;;;:::i;66914:95::-;66961:7;66987:15;:6;:13;:15::i;:::-;66980:22;;66914:95;:::o;66801:107::-;66858:7;66884:17;66858:7;66894:6;66884:9;:17::i;:::-;66877:24;66801:107;-1:-1:-1;;66801:107:0:o;66694:101::-;66738:16;66773:15;:6;:13;:15::i;60447:115::-;60510:7;60536:19;60544:3;56062:18;;55980:107;60904:156;60978:7;61028:22;61032:3;61044:5;61028:3;:22::i;:::-;61020:31;60904:156;-1:-1:-1;;;60904:156:0:o;61600:257::-;61663:16;61691:22;61716:19;61724:3;61716:7;:19::i;56429:118::-;56496:7;56522:3;:11;;56534:5;56522:18;;;;;;;;:::i;:::-;;;;;;;;;56515:25;;56429:118;;;;:::o;57087:109::-;57143:16;57178:3;:11;;57171:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57087:109;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;612:681::-;783:2;835:21;;;905:13;;808:18;;;927:22;;;754:4;;783:2;1006:15;;;;980:2;965:18;;;754:4;1049:218;1063:6;1060:1;1057:13;1049:218;;;1128:13;;1143:42;1124:62;1112:75;;1242:15;;;;1207:12;;;;1085:1;1078:9;1049:218;;;-1:-1:-1;1284:3:1;;612:681;-1:-1:-1;;;;;;612:681:1:o;1298:184::-;1350:77;1347:1;1340:88;1447:4;1444:1;1437:15;1471:4;1468:1;1461:15","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"GuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"allGuards()":"9fe03fa2","getGuard(uint256)":"629ddf69","guardsAmount()":"246c2449"}},"solidity/ReplicaManagerHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207d3257341cdd3bb04530f9b314f4dd3280b9bc08548d24a28d3931411dc7896d64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207d3257341cdd3bb04530f9b314f4dd3280b9bc08548d24a28d3931411dc7896d64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"85258:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;85258:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"85258:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:IMessageRecipient":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_origin","type":"uint32"},{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"uint256","name":"_rootTimestamp","type":"uint256"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"handle","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_origin\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_sender\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_rootTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"handle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"IMessageRecipient\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"handle(uint32,uint32,bytes32,uint256,bytes)":"e4d16d62"}},"solidity/ReplicaManagerHarness.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/ReplicaManagerHarness.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"custom:oz-upgrades-unsafe-allow":"constructor constructor() { _disableInitializers(); } ``` ====","details":"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\"MyToken\", \"MTK\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\"MyToken\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```","events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor constructor() { _disableInitializers(); } ``` ====\",\"details\":\"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\\\"MyToken\\\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209f3b9af459a0eb5a59dfc41d8c8a4b26c6a43ff276f126dfc6dba7e8d57d56d164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209f3b9af459a0eb5a59dfc41d8c8a4b26c6a43ff276f126dfc6dba7e8d57d56d164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"71149:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;71149:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"71149:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220136bbd8b0d2958472f7ed999406834e4db6caf7b7584da8ea508e848b36d40dd64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220136bbd8b0d2958472f7ed999406834e4db6caf7b7584da8ea508e848b36d40dd64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80285:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;80285:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"80285:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManagerHarness.sol:ReplicaLib":{"code":"0x6098610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212205c7eae674429e9cf7baf8c5c1a192fbb52dda29281abdea12a1ef394e035993764736f6c634300080d0033","runtime-code":"0x7300000000000000000000000000000000000000003014608060405260043610603d5760003560e01c8063643d8086146042578063b007581814605b575b600080fd5b6049600181565b60405190815260200160405180910390f35b604960008156fea26469706673582212205c7eae674429e9cf7baf8c5c1a192fbb52dda29281abdea12a1ef394e035993764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"68148:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;68148:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"68148:2999:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69217:70;;69284:1;69217:70;;;;;168:25:1;;;156:2;141:18;69217:70:0;;;;;;;69155:56;;69209:1;69155:56;","abiDefinition":[{"inputs":[],"name":"MESSAGE_STATUS_NONE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_STATUS_PROCESSED","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"MESSAGE_STATUS_NONE":{"details":"Should not be possible to have 0x0 or 0x1 as valid Merkle root, so it's safe to use those values as NONE/PROCESSED"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"MESSAGE_STATUS_NONE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MESSAGE_STATUS_PROCESSED\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"MESSAGE_STATUS_NONE\":{\"details\":\"Should not be possible to have 0x0 or 0x1 as valid Merkle root, so it's safe to use those values as NONE/PROCESSED\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ReplicaLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"MESSAGE_STATUS_NONE()":"b0075818","MESSAGE_STATUS_PROCESSED()":"643d8086"}},"solidity/ReplicaManagerHarness.sol:ReplicaManager":{"code":"0x60a06040523480156200001157600080fd5b5060405162002f5238038062002f52833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b608051612eb66200009c600039600081816102cf015281816109240152610f310152612eb66000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638d3638f4116100d8578063b65672d31161008c578063f2fde38b11610066578063f2fde38b146103c8578063f646a512146103db578063ffa1ad74146103ee57600080fd5b8063b65672d31461035f578063b7bc563e14610395578063ccbdf9c9146103a857600080fd5b8063928bc4b2116100bd578063928bc4b2146103245780639df7d36d146103375780639fe03fa21461034a57600080fd5b80638d3638f4146102ca5780638da5cb5b1461030657600080fd5b8063634155141161012f578063715018a611610114578063715018a61461026e5780637dfdba28146102765780638624c35c146102b757600080fd5b8063634155141461021a578063687052751461025b57600080fd5b80634f63be3f116101605780634f63be3f146101ba57806361bc3111146101cd578063629ddf69146101e257600080fd5b806315a046aa1461017c578063246c2449146101a4575b600080fd5b61018f61018a366004612824565b610408565b60405190151581526020015b60405180910390f35b6101ac610465565b60405190815260200161019b565b61018f6101c836600461293a565b610476565b6101e06101db3660046129cc565b6105f0565b005b6101f56101f0366004612a03565b610666565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101ac610228366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b6101e061026936600461293a565b610679565b6101e06106e0565b6101ac610284366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b6101e06102c53660046129cc565b610749565b6102f17f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019b565b60335473ffffffffffffffffffffffffffffffffffffffff166101f5565b6101e0610332366004612a46565b6108cb565b6101e0610345366004612a7b565b610c67565b610352610d5b565b60405161019b9190612aae565b6102f161036d366004612b08565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b6101e06103a3366004612b23565b610d67565b6065546101f59073ffffffffffffffffffffffffffffffffffffffff1681565b6101e06103d6366004612b23565b610e15565b6101e06103e9366004612a46565b610f0e565b6103f6600081565b60405160ff909116815260200161019b565b63ffffffff8316600090815260ce6020908152604080832054835260cd825280832084845260010190915281205480820361044757600091505061045e565b61045763ffffffff851682612b6f565b4210159150505b9392505050565b600061047160986110e9565b905090565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff1660028111156104c5576104c5612b87565b146105175760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105755760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e6500000000000000000000000000604482015260640161050e565b60006105ab8387602080602002604051908101604052809291908260208002808284376000920191909152508991506110f39050565b6000818152600184016020526040902054909150156105e05760009283526002919091016020526040909120555060016105e8565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106575760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b6106618282611199565b505050565b6000610673609883611296565b92915050565b61068584848484610476565b6106d15760405162461bcd60e51b815260206004820152600660248201527f2170726f76650000000000000000000000000000000000000000000000000000604482015260640161050e565b6106da836108cb565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b565b600061075560016112a2565b9050801561078a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6107926113f9565b61079c8383611199565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561084e8360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561066157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60006108d68261147e565b905060006108e962ffffff19831661148c565b905060006108fc62ffffff1983166114cc565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661095362ffffff1985166114f6565b63ffffffff16146109a65760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e0000000000000000000000000000000000000000604482015260640161050e565b60006109b762ffffff198616611517565b60008181526002840160205260409020549091506109d481611574565b610a205760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f636573736564000000000000000000000000604482015260640161050e565b610a3984610a3362ffffff198816611588565b83610408565b610a855760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e64730000000000000000000000000000604482015260640161050e565b60cb5460ff16600114610ada5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e7400000000000000000000000000000000000000000000604482015260640161050e565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b17610b1462ffffff1988166115a9565b50565b6000828152600284016020526040812060019055610b42610b3d62ffffff1988166115e0565b611601565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b7062ffffff198a16611643565b610b7f62ffffff198b16611664565b600087815260018a016020526040902054610bad610ba262ffffff198f16611685565b62ffffff19166116c4565b6040518663ffffffff1660e01b8152600401610bcd959493929190612c21565b600060405180830381600087803b158015610be757600080fd5b505af1158015610bfb573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610d119083908690869061171716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b6060610471609861172b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e7c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b73ffffffffffffffffffffffffffffffffffffffff8116610f055760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161050e565b610b1481611738565b6000610f19826117af565b9150506000610f2d8262ffffff19166118e9565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610faa5760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e00000000604482015260640161050e565b6000610fbb62ffffff1984166118fd565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116110365760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e7420737461746500604482015260640161050e565b600061104762ffffff198616611911565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6110cc610ba28a62ffffff1916611926565b6040516110d99190612c61565b60405180910390a4505050505050565b6000610673825490565b8260005b602081101561119157600183821c16600085836020811061111a5761111a612c74565b602002015190508160010361115a576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611187565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b50506001016110f7565b509392505050565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156111dd57506000610673565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b600061045e8383611959565b60008054610100900460ff161561133f578160ff1660011480156112c55750303b155b6113375760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b506000919050565b60005460ff8084169116106113bc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114765760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b610747611983565b600061067382610539611a09565b6000816114a162ffffff198216610539611a2d565b506114c3836114b1856001611b2e565b6114bc866002611b2e565b6001611b60565b91505b50919050565b6000816114e260015b62ffffff19831690611a2d565b506114c362ffffff19841660026004611b7f565b60008161150360016114d5565b506114c362ffffff198416602a6004611b7f565b6000806115328360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061155c8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906106735750506001141590565b60008161159560016114d5565b506114c362ffffff198416604e6004611b7f565b6000816115be62ffffff198216610539611a2d565b506114c3836115ce856002611b2e565b6115d9866003611b2e565b6002611b60565b6000816115ed60016114d5565b506114c362ffffff198416602e6020611baf565b600074010000000000000000000000000000000000000000820161163d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b81610673565b60008161165060016114d5565b506114c362ffffff19841660266004611b7f565b60008161167160016114d5565b506114c362ffffff19841660066020611baf565b60008161169a62ffffff198216610539611a2d565b506114c3836116aa856003611b2e565b601886901c6bffffffffffffffffffffffff166003611b60565b60606000806116e18460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117068483602001611d6d565b508181016020016040529052919050565b600091825260019092016020526040902055565b6060600061045e83611f12565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806117bc8382611a09565b905060286bffffffffffffffffffffffff601883901c16116118205760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161050e565b61184961183262ffffff198316611f6e565b611844610ba262ffffff198516611926565b611f83565b915061189861185d62ffffff1983166118e9565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6118e45760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161050e565b915091565b600061067362ffffff198316826004611b7f565b600061067362ffffff198316600480611b7f565b600061067362ffffff19831660086020611baf565b6000610673602861194981601886901c6bffffffffffffffffffffffff16612ca3565b62ffffff19851691906000611ffa565b600082600001828154811061197057611970612c74565b9060005260206000200154905092915050565b600054610100900460ff16611a005760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b61074733611738565b815160009060208401611a2464ffffffffff85168284612070565b95945050505050565b6000611a3983836120b7565b611b27576000611a58611a4c8560d81c90565b64ffffffffff166120da565b9150506000611a6d8464ffffffffff166120da565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161050e9190612c61565b5090919050565b600061045e6002836004811115611b4757611b47612b87565b611b519190612cba565b62ffffff198516906002611b7f565b6000611a2484611b708186612ca3565b62ffffff198816919085611ffa565b6000611b8c826020612cf7565b611b97906008612d1a565b60ff16611ba5858585611baf565b901c949350505050565b60008160ff16600003611bc45750600061045e565b611bdc8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611bf760ff841685612b6f565b1115611c6f57611c56611c188560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611c3e8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166121c4565b60405162461bcd60e51b815260040161050e9190612c61565b60208260ff161115611ce95760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161050e565b600882026000611d078660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611dea5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161050e565b611df383612232565b611e655760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161050e565b6000611e7f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611ea98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611ece5760206060fd5b8285848460045afa50611f08611ee48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611f6257602002820191906000526020600020905b815481526020019060010190808311611f4e575b50505050509050919050565b600061067362ffffff19831682602881611ffa565b600080611f9562ffffff198516611517565b9050611fee816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506105e8818461226f565b6000806120158660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061202e8661228b565b846120398784612b6f565b6120439190612b6f565b11156120565762ffffff199150506105e8565b6120608582612b6f565b9050611f088364ffffffffff1682865b60008061207d8385612b6f565b905060405181111561208d575060005b806000036120a25762ffffff1991505061045e565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166120cb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561214d5760006120f9826008612d1a565b60ff1685901c905061210a816122d3565b61ffff16841793508160ff1660101461212557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016120e0565b50600f5b60ff8160ff1610156121be57600061216a826008612d1a565b60ff1685901c905061217b816122d3565b61ffff16831792508160ff1660001461219657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612151565b50915091565b606060006121d1866120da565b91505060006121df866120da565b91505060006121ed866120da565b91505060006121fb866120da565b915050838383836040516020016122159493929190612d43565b604051602081830303815290604052945050505050949350505050565b600061223e8260d81c90565b64ffffffffff1664ffffffffff0361225857506000919050565b60006122638361228b565b60405110199392505050565b600080600061227e8585612305565b9150915061119181612373565b60006122a58260181c6bffffffffffffffffffffffff1690565b6122bd8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006122e560048360ff16901c61255f565b60ff1661ffff919091161760081b6122fc8261255f565b60ff1617919050565b600080825160410361233b5760208301516040840151606085015160001a61232f878285856126a6565b9450945050505061236c565b825160400361236457602083015160408401516123598683836127be565b93509350505061236c565b506000905060025b9250929050565b600081600481111561238757612387612b87565b0361238f5750565b60018160048111156123a3576123a3612b87565b036123f05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161050e565b600281600481111561240457612404612b87565b036124515760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161050e565b600381600481111561246557612465612b87565b036124d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b60048160048111156124ec576124ec612b87565b03610b145760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b600060f08083179060ff8216900361257a5750603092915050565b8060ff1660f10361258e5750603192915050565b8060ff1660f2036125a25750603292915050565b8060ff1660f3036125b65750603392915050565b8060ff1660f4036125ca5750603492915050565b8060ff1660f5036125de5750603592915050565b8060ff1660f6036125f25750603692915050565b8060ff1660f7036126065750603792915050565b8060ff1660f80361261a5750603892915050565b8060ff1660f90361262e5750603992915050565b8060ff1660fa036126425750606192915050565b8060ff1660fb036126565750606292915050565b8060ff1660fc0361266a5750606392915050565b8060ff1660fd0361267e5750606492915050565b8060ff1660fe036126925750606592915050565b8060ff1660ff036114c65750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126dd57506000905060036127b5565b8460ff16601b141580156126f557508460ff16601c14155b1561270657506000905060046127b5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561275a573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166127ae576000600192509250506127b5565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816127f460ff86901c601b612b6f565b9050612802878288856126a6565b935093505050935093915050565b803563ffffffff811681146113f457600080fd5b60008060006060848603121561283957600080fd5b61284284612810565b925061285060208501612810565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126128a057600080fd5b813567ffffffffffffffff808211156128bb576128bb612860565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561290157612901612860565b8160405283815286602085880101111561291a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561295157600080fd5b61295a85612810565b9350602085013567ffffffffffffffff81111561297657600080fd5b6129828782880161288f565b93505061044085018681111561299757600080fd5b9396929550505060409290920191903590565b73ffffffffffffffffffffffffffffffffffffffff81168114610b1457600080fd5b600080604083850312156129df57600080fd5b6129e883612810565b915060208301356129f8816129aa565b809150509250929050565b600060208284031215612a1557600080fd5b5035919050565b60008060408385031215612a2f57600080fd5b612a3883612810565b946020939093013593505050565b600060208284031215612a5857600080fd5b813567ffffffffffffffff811115612a6f57600080fd5b6105e88482850161288f565b600080600060608486031215612a9057600080fd5b612a9984612810565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612afc57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612aca565b50909695505050505050565b600060208284031215612b1a57600080fd5b61045e82612810565b600060208284031215612b3557600080fd5b813561045e816129aa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612b8257612b82612b40565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612bdc57602081850181015186830182015201612bc0565b81811115612bee576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612c5660a0830184612bb6565b979650505050505050565b60208152600061045e6020830184612bb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612cb557612cb5612b40565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612cf257612cf2612b40565b500290565b600060ff821660ff841680821015612d1157612d11612b40565b90039392505050565b600060ff821660ff84168160ff0481118215151615612d3b57612d3b612b40565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611f0856fea264697066735822122091ca50ae4e0182c9cc516c0057abe5efe055e56b91b8e4ec3918ea89f4487f6c64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106101775760003560e01c80638d3638f4116100d8578063b65672d31161008c578063f2fde38b11610066578063f2fde38b146103c8578063f646a512146103db578063ffa1ad74146103ee57600080fd5b8063b65672d31461035f578063b7bc563e14610395578063ccbdf9c9146103a857600080fd5b8063928bc4b2116100bd578063928bc4b2146103245780639df7d36d146103375780639fe03fa21461034a57600080fd5b80638d3638f4146102ca5780638da5cb5b1461030657600080fd5b8063634155141161012f578063715018a611610114578063715018a61461026e5780637dfdba28146102765780638624c35c146102b757600080fd5b8063634155141461021a578063687052751461025b57600080fd5b80634f63be3f116101605780634f63be3f146101ba57806361bc3111146101cd578063629ddf69146101e257600080fd5b806315a046aa1461017c578063246c2449146101a4575b600080fd5b61018f61018a366004612824565b610408565b60405190151581526020015b60405180910390f35b6101ac610465565b60405190815260200161019b565b61018f6101c836600461293a565b610476565b6101e06101db3660046129cc565b6105f0565b005b6101f56101f0366004612a03565b610666565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b6101ac610228366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b6101e061026936600461293a565b610679565b6101e06106e0565b6101ac610284366004612a1c565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b6101e06102c53660046129cc565b610749565b6102f17f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161019b565b60335473ffffffffffffffffffffffffffffffffffffffff166101f5565b6101e0610332366004612a46565b6108cb565b6101e0610345366004612a7b565b610c67565b610352610d5b565b60405161019b9190612aae565b6102f161036d366004612b08565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b6101e06103a3366004612b23565b610d67565b6065546101f59073ffffffffffffffffffffffffffffffffffffffff1681565b6101e06103d6366004612b23565b610e15565b6101e06103e9366004612a46565b610f0e565b6103f6600081565b60405160ff909116815260200161019b565b63ffffffff8316600090815260ce6020908152604080832054835260cd825280832084845260010190915281205480820361044757600091505061045e565b61045763ffffffff851682612b6f565b4210159150505b9392505050565b600061047160986110e9565b905090565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff1660028111156104c5576104c5612b87565b146105175760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b6000828152600282016020526040902054156105755760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e6500000000000000000000000000604482015260640161050e565b60006105ab8387602080602002604051908101604052809291908260208002808284376000920191909152508991506110f39050565b6000818152600184016020526040902054909150156105e05760009283526002919091016020526040909120555060016105e8565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146106575760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b6106618282611199565b505050565b6000610673609883611296565b92915050565b61068584848484610476565b6106d15760405162461bcd60e51b815260206004820152600660248201527f2170726f76650000000000000000000000000000000000000000000000000000604482015260640161050e565b6106da836108cb565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b565b600061075560016112a2565b9050801561078a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6107926113f9565b61079c8383611199565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561084e8360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561066157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b60006108d68261147e565b905060006108e962ffffff19831661148c565b905060006108fc62ffffff1983166114cc565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f00000000000000000000000000000000000000000000000000000000000000001661095362ffffff1985166114f6565b63ffffffff16146109a65760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e0000000000000000000000000000000000000000604482015260640161050e565b60006109b762ffffff198616611517565b60008181526002840160205260409020549091506109d481611574565b610a205760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f636573736564000000000000000000000000604482015260640161050e565b610a3984610a3362ffffff198816611588565b83610408565b610a855760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e64730000000000000000000000000000604482015260640161050e565b60cb5460ff16600114610ada5760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e7400000000000000000000000000000000000000000000604482015260640161050e565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b17610b1462ffffff1988166115a9565b50565b6000828152600284016020526040812060019055610b42610b3d62ffffff1988166115e0565b611601565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610b7062ffffff198a16611643565b610b7f62ffffff198b16611664565b600087815260018a016020526040902054610bad610ba262ffffff198f16611685565b62ffffff19166116c4565b6040518663ffffffff1660e01b8152600401610bcd959493929190612c21565b600060405180830381600087803b158015610be757600080fd5b505af1158015610bfb573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610cce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610d119083908690869061171716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b6060610471609861172b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610dce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e7c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161050e565b73ffffffffffffffffffffffffffffffffffffffff8116610f055760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161050e565b610b1481611738565b6000610f19826117af565b9150506000610f2d8262ffffff19166118e9565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff1603610faa5760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e00000000604482015260640161050e565b6000610fbb62ffffff1984166118fd565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116110365760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e7420737461746500604482015260640161050e565b600061104762ffffff198616611911565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6110cc610ba28a62ffffff1916611926565b6040516110d99190612c61565b60405180910390a4505050505050565b6000610673825490565b8260005b602081101561119157600183821c16600085836020811061111a5761111a612c74565b602002015190508160010361115a576040805160208101839052908101859052606001604051602081830303815290604052805190602001209350611187565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b50506001016110f7565b509392505050565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156111dd57506000610673565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b600061045e8383611959565b60008054610100900460ff161561133f578160ff1660011480156112c55750303b155b6113375760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b506000919050565b60005460ff8084169116106113bc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161050e565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166114765760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b610747611983565b600061067382610539611a09565b6000816114a162ffffff198216610539611a2d565b506114c3836114b1856001611b2e565b6114bc866002611b2e565b6001611b60565b91505b50919050565b6000816114e260015b62ffffff19831690611a2d565b506114c362ffffff19841660026004611b7f565b60008161150360016114d5565b506114c362ffffff198416602a6004611b7f565b6000806115328360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061155c8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600081158015906106735750506001141590565b60008161159560016114d5565b506114c362ffffff198416604e6004611b7f565b6000816115be62ffffff198216610539611a2d565b506114c3836115ce856002611b2e565b6115d9866003611b2e565b6002611b60565b6000816115ed60016114d5565b506114c362ffffff198416602e6020611baf565b600074010000000000000000000000000000000000000000820161163d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b81610673565b60008161165060016114d5565b506114c362ffffff19841660266004611b7f565b60008161167160016114d5565b506114c362ffffff19841660066020611baf565b60008161169a62ffffff198216610539611a2d565b506114c3836116aa856003611b2e565b601886901c6bffffffffffffffffffffffff166003611b60565b60606000806116e18460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117068483602001611d6d565b508181016020016040529052919050565b600091825260019092016020526040902055565b6060600061045e83611f12565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806117bc8382611a09565b905060286bffffffffffffffffffffffff601883901c16116118205760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161050e565b61184961183262ffffff198316611f6e565b611844610ba262ffffff198516611926565b611f83565b915061189861185d62ffffff1983166118e9565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b6118e45760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f7461727900000000000000000000604482015260640161050e565b915091565b600061067362ffffff198316826004611b7f565b600061067362ffffff198316600480611b7f565b600061067362ffffff19831660086020611baf565b6000610673602861194981601886901c6bffffffffffffffffffffffff16612ca3565b62ffffff19851691906000611ffa565b600082600001828154811061197057611970612c74565b9060005260206000200154905092915050565b600054610100900460ff16611a005760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161050e565b61074733611738565b815160009060208401611a2464ffffffffff85168284612070565b95945050505050565b6000611a3983836120b7565b611b27576000611a58611a4c8560d81c90565b64ffffffffff166120da565b9150506000611a6d8464ffffffffff166120da565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161050e9190612c61565b5090919050565b600061045e6002836004811115611b4757611b47612b87565b611b519190612cba565b62ffffff198516906002611b7f565b6000611a2484611b708186612ca3565b62ffffff198816919085611ffa565b6000611b8c826020612cf7565b611b97906008612d1a565b60ff16611ba5858585611baf565b901c949350505050565b60008160ff16600003611bc45750600061045e565b611bdc8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611bf760ff841685612b6f565b1115611c6f57611c56611c188560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611c3e8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166121c4565b60405162461bcd60e51b815260040161050e9190612c61565b60208260ff161115611ce95760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161050e565b600882026000611d078660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff1980841603611dea5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161050e565b611df383612232565b611e655760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161050e565b6000611e7f8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000611ea98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506000604051905084811115611ece5760206060fd5b8285848460045afa50611f08611ee48760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611f6257602002820191906000526020600020905b815481526020019060010190808311611f4e575b50505050509050919050565b600061067362ffffff19831682602881611ffa565b600080611f9562ffffff198516611517565b9050611fee816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506105e8818461226f565b6000806120158660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905061202e8661228b565b846120398784612b6f565b6120439190612b6f565b11156120565762ffffff199150506105e8565b6120608582612b6f565b9050611f088364ffffffffff1682865b60008061207d8385612b6f565b905060405181111561208d575060005b806000036120a25762ffffff1991505061045e565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff166120cb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561214d5760006120f9826008612d1a565b60ff1685901c905061210a816122d3565b61ffff16841793508160ff1660101461212557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016120e0565b50600f5b60ff8160ff1610156121be57600061216a826008612d1a565b60ff1685901c905061217b816122d3565b61ffff16831792508160ff1660001461219657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612151565b50915091565b606060006121d1866120da565b91505060006121df866120da565b91505060006121ed866120da565b91505060006121fb866120da565b915050838383836040516020016122159493929190612d43565b604051602081830303815290604052945050505050949350505050565b600061223e8260d81c90565b64ffffffffff1664ffffffffff0361225857506000919050565b60006122638361228b565b60405110199392505050565b600080600061227e8585612305565b9150915061119181612373565b60006122a58260181c6bffffffffffffffffffffffff1690565b6122bd8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b60006122e560048360ff16901c61255f565b60ff1661ffff919091161760081b6122fc8261255f565b60ff1617919050565b600080825160410361233b5760208301516040840151606085015160001a61232f878285856126a6565b9450945050505061236c565b825160400361236457602083015160408401516123598683836127be565b93509350505061236c565b506000905060025b9250929050565b600081600481111561238757612387612b87565b0361238f5750565b60018160048111156123a3576123a3612b87565b036123f05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161050e565b600281600481111561240457612404612b87565b036124515760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161050e565b600381600481111561246557612465612b87565b036124d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b60048160048111156124ec576124ec612b87565b03610b145760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161050e565b600060f08083179060ff8216900361257a5750603092915050565b8060ff1660f10361258e5750603192915050565b8060ff1660f2036125a25750603292915050565b8060ff1660f3036125b65750603392915050565b8060ff1660f4036125ca5750603492915050565b8060ff1660f5036125de5750603592915050565b8060ff1660f6036125f25750603692915050565b8060ff1660f7036126065750603792915050565b8060ff1660f80361261a5750603892915050565b8060ff1660f90361262e5750603992915050565b8060ff1660fa036126425750606192915050565b8060ff1660fb036126565750606292915050565b8060ff1660fc0361266a5750606392915050565b8060ff1660fd0361267e5750606492915050565b8060ff1660fe036126925750606592915050565b8060ff1660ff036114c65750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126dd57506000905060036127b5565b8460ff16601b141580156126f557508460ff16601c14155b1561270657506000905060046127b5565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561275a573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166127ae576000600192509250506127b5565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816127f460ff86901c601b612b6f565b9050612802878288856126a6565b935093505050935093915050565b803563ffffffff811681146113f457600080fd5b60008060006060848603121561283957600080fd5b61284284612810565b925061285060208501612810565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126128a057600080fd5b813567ffffffffffffffff808211156128bb576128bb612860565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561290157612901612860565b8160405283815286602085880101111561291a57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080610460858703121561295157600080fd5b61295a85612810565b9350602085013567ffffffffffffffff81111561297657600080fd5b6129828782880161288f565b93505061044085018681111561299757600080fd5b9396929550505060409290920191903590565b73ffffffffffffffffffffffffffffffffffffffff81168114610b1457600080fd5b600080604083850312156129df57600080fd5b6129e883612810565b915060208301356129f8816129aa565b809150509250929050565b600060208284031215612a1557600080fd5b5035919050565b60008060408385031215612a2f57600080fd5b612a3883612810565b946020939093013593505050565b600060208284031215612a5857600080fd5b813567ffffffffffffffff811115612a6f57600080fd5b6105e88482850161288f565b600080600060608486031215612a9057600080fd5b612a9984612810565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612afc57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612aca565b50909695505050505050565b600060208284031215612b1a57600080fd5b61045e82612810565b600060208284031215612b3557600080fd5b813561045e816129aa565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612b8257612b82612b40565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612bdc57602081850181015186830182015201612bc0565b81811115612bee576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612c5660a0830184612bb6565b979650505050505050565b60208152600061045e6020830184612bb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612cb557612cb5612b40565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612cf257612cf2612b40565b500290565b600060ff821660ff841680821015612d1157612d11612b40565b90039392505050565b600060ff821660ff84168160ff0481118215151615612d3b57612d3b612b40565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d8201611f0856fea264697066735822122091ca50ae4e0182c9cc516c0057abe5efe055e56b91b8e4ec3918ea89f4487f6c64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"118470:12750:0:-:0;;;120516:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115172:26;;;;118470:12750;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;118470:12750:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"118470:12750:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;127486:361;;;;;;:::i;:::-;;:::i;:::-;;;676:14:1;;669:22;651:41;;639:2;624:18;127486:361:0;;;;;;;;66914:95;;;:::i;:::-;;;849:25:1;;;837:2;822:18;66914:95:0;703:177:1;128509:1028:0;;;;;;:::i;:::-;;:::i;126187:158::-;;;;;;:::i;:::-;;:::i;:::-;;66801:107;;;;;;:::i;:::-;;:::i;:::-;;;3314:42:1;3302:55;;;3284:74;;3272:2;3257:18;66801:107:0;3138:226:1;121819:230:0;;;;;;:::i;:::-;121986:29;;;;;121944:7;121986:29;;;:14;:29;;;;;;;;;121974:42;;:11;:42;;;;;:68;;;:56;;;;:68;;;;;121819:230;123772:271;;;;;;:::i;:::-;;:::i;117488:57::-;;;:::i;121599:214::-;;;;;;:::i;:::-;121759:29;;;;;121717:7;121759:29;;;:14;:29;;;;;;;;;121747:42;;:11;:42;;;;;:59;;;:52;;;;:59;;;;;121599:214;121084:295;;;;;;:::i;:::-;;:::i;113961:35::-;;;;;;;;3982:10:1;3970:23;;;3952:42;;3940:2;3925:18;113961:35:0;3808:192:1;111644:85:0;111716:6;;;;111644:85;;124481:1415;;;;;;:::i;:::-;;:::i;126696:423::-;;;;;;:::i;:::-;;:::i;66694:101::-;;;:::i;:::-;;;;;;;:::i;121440:153::-;;;;;;:::i;:::-;121550:29;;;;121513:6;121550:29;;;:14;:29;;;;;;;;;121538:42;;:11;:42;;;;;:48;;;121440:153;117162:133;;;;;;:::i;:::-;;:::i;114543:39::-;;;;;;;;;112526:198;;;;;;:::i;:::-;;:::i;122539:801::-;;;;;;:::i;:::-;;:::i;68110:33::-;;68142:1;68110:33;;;;;6487:4:1;6475:17;;;6457:36;;6445:2;6430:18;68110:33:0;6315:184:1;127486:361:0;127669:29;;;127625:4;127669:29;;;:14;:29;;;;;;;;;127657:42;;:11;:42;;;;;:59;;;:52;;:59;;;;;;127730:10;;;127726:53;;127763:5;127756:12;;;;;127726:53;127814:26;;;;:5;:26;:::i;:::-;127795:15;:45;;127788:52;;;127486:361;;;;;;:::o;66914:95::-;66961:7;66987:15;:6;:13;:15::i;:::-;66980:22;;66914:95;:::o;128509:1028::-;128700:19;;;;;;;;;;128778:29;;;128668:4;128778:29;;;:14;:29;;;;;;;128766:42;;:11;:42;;;;;;128885:31;128867:14;;;;;;;:49;;;;;;;;:::i;:::-;;128859:80;;;;-1:-1:-1;;;128859:80:0;;7217:2:1;128859:80:0;;;7199:21:1;7256:2;7236:18;;;7229:30;7295:20;7275:18;;;7268:48;7333:18;;128859:80:0;;;;;;;;;69209:1;129034:28;;;:21;;;:28;;;;;;:62;129013:128;;;;-1:-1:-1;;;129013:128:0;;7564:2:1;129013:128:0;;;7546:21:1;7603:2;7583:18;;;7576:30;7642:21;7622:18;;;7615:49;7681:18;;129013:128:0;7362:343:1;129013:128:0;129209:23;129235:43;129256:5;129263:6;129235:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;129271:6:0;;-1:-1:-1;129235:20:0;;-1:-1:-1;129235:43:0:i;:::-;129370:34;;;;:17;;;:34;;;;;;129209:69;;-1:-1:-1;129370:39:0;129366:143;;70782:35;;;;:21;;;;;:35;;;;;;:45;-1:-1:-1;129494:4:0;129487:11;;129366:143;129525:5;129518:12;;;;;128509:1028;;;;;;;:::o;126187:158::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;126309:29:::1;126320:7;126329:8;126309:10;:29::i;:::-;;126187:158:::0;;:::o;66801:107::-;66858:7;66884:17;:6;66894;66884:9;:17::i;:::-;66877:24;66801:107;-1:-1:-1;;66801:107:0:o;123772:271::-;123952:46;123958:13;123973:8;123983:6;123991;123952:5;:46::i;:::-;123944:65;;;;-1:-1:-1;;;123944:65:0;;8273:2:1;123944:65:0;;;8255:21:1;8312:1;8292:18;;;8285:29;8350:8;8330:18;;;8323:36;8376:18;;123944:65:0;8071:329:1;123944:65:0;124019:17;124027:8;124019:7;:17::i;:::-;123772:271;;;;:::o;117488:57::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;117488:57::o;121084:295::-;106824:19;106846:25;106869:1;106846:22;:25::i;:::-;106824:47;;106885:14;106881:65;;;106915:13;:20;;;;;;;;106881:65;121173:29:::1;:27;:29::i;:::-;121212:35;121223:13;121238:8;121212:10;:35::i;:::-;-1:-1:-1::0;121290:7:0::1;:11:::0;;;::::1;121300:1;121290:11;::::0;;121343:29:::1;121358:13:::0;129826:12;;129841:1;129826:16;129660:20;129862:25;;;:11;:25;;;;;70254:36;;;;;;;70300:37;;;;;;;;;;;129925:12;:27;;;129940:12;129596:363;-1:-1:-1;129596:363:0;121343:29:::1;121311;::::0;::::1;;::::0;;;:14:::1;:29;::::0;;;;:61;106966:99;;;;107016:5;107000:21;;;;;;107040:14;;-1:-1:-1;6457:36:1;;107040:14:0;;6445:2:1;6430:18;107040:14:0;;;;;;;106814:257;121084:295;;:::o;124481:1415::-;124538:10;124551:22;:8;:20;:22::i;:::-;124538:35;-1:-1:-1;124583:15:0;124601:11;-1:-1:-1;;124601:9:0;;;:11::i;:::-;124583:29;-1:-1:-1;124622:20:0;124645:16;-1:-1:-1;;124645:14:0;;;:16::i;:::-;124720:29;;;;124671:34;124720:29;;;:14;:29;;;;;;;;;124708:42;;:11;:42;;;;;124622:39;;-1:-1:-1;124845:11:0;124820:36;:21;-1:-1:-1;;124820:19:0;;;:21::i;:::-;:36;;;124812:61;;;;-1:-1:-1;;;124812:61:0;;8806:2:1;124812:61:0;;;8788:21:1;8845:2;8825:18;;;8818:30;8884:14;8864:18;;;8857:42;8916:18;;124812:61:0;8604:336:1;124812:61:0;124925:20;124948:11;-1:-1:-1;;124948:9:0;;;:11::i;:::-;124969:13;124985:35;;;:21;;;:35;;;;;;124925:34;;-1:-1:-1;125038:33:0;124985:35;125038:26;:33::i;:::-;125030:66;;;;-1:-1:-1;;;125030:66:0;;9147:2:1;125030:66:0;;;9129:21:1;9186:2;9166:18;;;9159:30;9225:22;9205:18;;;9198:50;9265:18;;125030:66:0;8945:344:1;125030:66:0;125127:65;125142:13;125157:27;-1:-1:-1;;125157:25:0;;;:27::i;:::-;125186:5;125127:14;:65::i;:::-;125106:130;;;;-1:-1:-1;;;125106:130:0;;9496:2:1;125106:130:0;;;9478:21:1;9535:2;9515:18;;;9508:30;9574:20;9554:18;;;9547:48;9612:18;;125106:130:0;9294:342:1;125106:130:0;125289:7;;;;;:12;125281:35;;;;-1:-1:-1;;;125281:35:0;;9843:2:1;125281:35:0;;;9825:21:1;9882:2;9862:18;;;9855:30;9921:12;9901:18;;;9894:40;9951:18;;125281:35:0;9641:334:1;125281:35:0;125326:7;:11;;;;;;125347:21;125358:9;-1:-1:-1;;125358:7:0;;;:9::i;:::-;112526:198;;125347:21;70782:35;;;;:21;;;:35;;;;;69284:1;70782:45;;125529:43;125552:19;-1:-1:-1;;125552:17:0;;;:19::i;:::-;125529:22;:43::i;:::-;125509:63;-1:-1:-1;125582:35:0;;;;125631:13;125658:15;-1:-1:-1;;125658:13:0;;;:15::i;:::-;125687:16;-1:-1:-1;;125687:14:0;;;:16::i;:::-;125717:24;;;;:17;;;:24;;;;;;125755:17;:9;-1:-1:-1;;125755:7:0;;;:9::i;:::-;-1:-1:-1;;125755:15:0;;:17::i;:::-;125582:200;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;125797:36:0;;125820:12;;-1:-1:-1;125797:36:0;;;;-1:-1:-1;125797:36:0;;;;;-1:-1:-1;;125878:7:0;:11;;;;125888:1;125878:11;;;-1:-1:-1;;;;;;124481:1415:0:o;126696:423::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;126886:29:::1;::::0;;::::1;126837:34;126886:29:::0;;;:14:::1;:29;::::0;;;;;;;;126874:42;;:11:::1;:42:::0;;;;;126955:24;;;:17:::1;::::0;::::1;:24:::0;;;;;;;126874:42;;126989:39:::1;::::0;126874:42;;126973:5;;127017:10;;126989:20:::1;:39;:::i;:::-;127043:69;::::0;;11241:25:1;;;11297:2;11282:18;;11275:34;;;127074:5:0;;127043:69:::1;::::0;::::1;::::0;::::1;::::0;11214:18:1;127043:69:0::1;;;;;;;126827:292;;126696:423:::0;;;:::o;66694:101::-;66738:16;66773:15;:6;:13;:15::i;117162:133::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;117254:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;117162:133::o;112526:198::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;7912:2:1;111848:68:0;;;7894:21:1;;;7931:18;;;7924:30;7990:34;7970:18;;;7963:62;8042:18;;111848:68:0;7710:356:1;111848:68:0;112614:22:::1;::::0;::::1;112606:73;;;::::0;-1:-1:-1;;;112606:73:0;;11522:2:1;112606:73:0::1;::::0;::::1;11504:21:1::0;11561:2;11541:18;;;11534:30;11600:34;11580:18;;;11573:62;11671:8;11651:18;;;11644:36;11697:19;;112606:73:0::1;11320:402:1::0;112606:73:0::1;112689:28;112708:8;112689:18;:28::i;122539:801::-:0;122615:13;122632:30;122649:12;122632:16;:30::i;:::-;122612:50;;;122672:19;122694:25;:5;:23;;;;:25::i;:::-;122672:47;;122753:11;122737:27;;:12;:27;;;122729:68;;;;-1:-1:-1;;;122729:68:0;;11929:2:1;122729:68:0;;;11911:21:1;11968:2;11948:18;;;11941:30;12007;11987:18;;;11980:58;12055:18;;122729:68:0;11727:352:1;122729:68:0;122807:12;122822:24;-1:-1:-1;;122822:22:0;;;:24::i;:::-;122905:28;;;;122856:34;122905:28;;;:14;:28;;;;;;;;;122893:41;;:11;:41;;;;;122960:13;;122807:39;;-1:-1:-1;122893:41:0;122960:13;;122952:21;;;;122944:65;;;;-1:-1:-1;;;122944:65:0;;12286:2:1;122944:65:0;;;12268:21:1;12325:2;12305:18;;;12298:30;12364:33;12344:18;;;12337:61;12415:18;;122944:65:0;12084:355:1;122944:65:0;123019:15;123037:23;-1:-1:-1;;123037:21:0;;;:23::i;:::-;70593:24;;;;:17;;;:24;;;;;123100:15;70593:37;;123019:41;-1:-1:-1;70427:22:0;;;;;;;;;;123266:7;123247:5;123188:145;;123221:12;123188:145;;;123287:36;:28;:5;:26;;;;:28::i;:36::-;123188:145;;;;;;:::i;:::-;;;;;;;;122602:738;;;;;122539:801;:::o;60447:115::-;60510:7;60536:19;60544:3;56062:18;;55980:107;74819:614;74998:5;74959:16;75014:413;71212:2;75034:1;:14;75014:413;;;75100:4;75085:11;;;75084:20;75066:15;75134:7;75095:1;75134:10;;;;;;;:::i;:::-;;;;;75118:26;;75162:7;75173:1;75162:12;75158:200;;75215:33;;;;;;13012:19:1;;;13047:12;;;13040:28;;;13084:12;;75215:33:0;;;;;;;;;;;;75205:44;;;;;;75194:55;;75158:200;;;75309:33;;;;;;13012:19:1;;;13047:12;;;13040:28;;;13084:12;;75309:33:0;;;;;;;;;;;;75299:44;;;;;;75288:55;;75158:200;-1:-1:-1;;75399:3:0;;75014:413;;;;74819:614;;;;;:::o;50841:327::-;52449:24;;;50912:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;50928:45;;-1:-1:-1;50968:5:0;50961:12;;50928:45;50983:23;;;;;;;:14;:23;;;;;;;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;51066:23;;;:30;;51030:15;:24;;;;;:33;;;;;;;;;:66;;;;51111:29;3284:74:1;;;51111:29:0;;3257:18:1;51111:29:0;;;;;;;-1:-1:-1;51157:4:0;50841:327;;;;:::o;60904:156::-;60978:7;61028:22;61032:3;61044:5;61028:3;:22::i;109000:808::-;109064:4;109397:13;;;;;;;109393:409;;;109451:7;:12;;109462:1;109451:12;:61;;;;-1:-1:-1;109506:4:0;97971:19;:23;109451:61;109426:166;;;;-1:-1:-1;;;109426:166:0;;13309:2:1;109426:166:0;;;13291:21:1;13348:2;13328:18;;;13321:30;13387:34;13367:18;;;13360:62;13458:16;13438:18;;;13431:44;13492:19;;109426:166:0;13107:410:1;109426:166:0;-1:-1:-1;109613:5:0;;109000:808;-1:-1:-1;109000:808:0:o;109393:409::-;109657:12;;:22;;;;:12;;:22;109649:81;;;;-1:-1:-1;;;109649:81:0;;13309:2:1;109649:81:0;;;13291:21:1;13348:2;13328:18;;;13321:30;13387:34;13367:18;;;13360:62;13458:16;13438:18;;;13431:44;13492:19;;109649:81:0;13107:410:1;109649:81:0;-1:-1:-1;109744:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;109000:808:0:o;109393:409::-;109000:808;;;:::o;115751:108::-;108411:13;;;;;;;108403:69;;;;-1:-1:-1;;;108403:69:0;;13724:2:1;108403:69:0;;;13706:21:1;13763:2;13743:18;;;13736:30;13802:34;13782:18;;;13775:62;13873:13;13853:18;;;13846:41;13904:19;;108403:69:0;13522:407:1;108403:69:0;115826:26:::1;:24;:26::i;83280:126::-:0;83347:7;83373:26;:8;80868:4;83373:12;:26::i;83530:305::-;83609:7;83590:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;83647:181:::1;83673:8;83699:35;83711:8;83721:12;83699:11;:35::i;:::-;83752:33;83764:8;83774:10;83752:11;:33::i;:::-;80924:12;83647:8;:181::i;:::-;83628:200;;81152:1;83530:305:::0;;;;:::o;87132:151::-;87208:6;87190:7;86212:37;80924:12;80917:20;-1:-1:-1;;86212:16:0;;;;:37::i;:::-;-1:-1:-1;87240:35:0::1;-1:-1:-1::0;;87240:17:0;::::1;85891:1;87273;87240:17;:35::i;87733:161::-:0;87814:6;87796:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87846:40:0::1;-1:-1:-1::0;;87846:17:0;::::1;86043:2;87884:1;87846:17;:40::i;22455:290::-:0;22511:14;22537:12;22552;22556:7;15386:3;15382:17;2670:26;15378:29;;15059:364;22552:12;22537:27;;;;22574:12;22589;22593:7;16492:2;16488:16;2670:26;16484:28;;16246:282;22589:12;22574:27;;22708:21;;;;22455:290;-1:-1:-1;;;22455:290:0:o;70963:182::-;71034:4;71057:36;;;;;:81;;-1:-1:-1;;69284:1:0;71097:41;;;70963:182::o;88171:174::-;88258:6;88240:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;88290:47:0::1;-1:-1:-1::0;;88290:17:0;::::1;86158:2;88335:1;88290:17;:47::i;83957:299::-:0;84034:7;84015:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;84072:177:::1;84098:8;84124:33;84136:8;84146:10;84124:11;:33::i;:::-;84175;84187:8;84197:10;84175:11;:33::i;:::-;80987:10;83647:8;:181::i;87960:147::-:0;88039:7;88021;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;88065:35:0::1;-1:-1:-1::0;;88065:13:0;::::1;86096:2;88097;88065:13;:35::i;130458:643::-:0;130533:17;130635:41;;;130631:464;;-1:-1:-1;;130938:15:0;;;;;109000:808::o;130631:464::-;131073:10;131046:38;80154:127;87527:149;87602:6;87584:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87634:34:0::1;-1:-1:-1::0;;87634:17:0;::::1;85988:2;87666:1;87634:17;:34::i;87335:141::-:0;87411:7;87393;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87437:32:0::1;-1:-1:-1::0;;87437:13:0;::::1;85940:1;87466:2;87437:13;:32::i;84378:190::-:0;84455:7;84436:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;84481:80:::1;84490:8;84500:33;84512:8;84522:10;84500:11;:33::i;:::-;16492:2:::0;16488:16;;;2670:26;16484:28;81048:10:::1;83647:8;:181::i;28308:632::-:0;28363:16;28391:11;28412:12;28427;28431:7;16492:2;16488:16;2670:26;16484:28;;16246:282;28427:12;28412:27;;;;28549:4;28543:11;28536:18;;28604:3;28597:10;;28650:33;28663:7;28672:3;28678:4;28672:10;28650:12;:33::i;:::-;-1:-1:-1;28807:14:0;;;28823:4;28803:25;28797:4;28790:39;28870:17;;28308:632;;-1:-1:-1;28308:632:0:o;70462:175::-;70593:24;;;;:17;;;;:24;;;;;:37;70462:175::o;61600:257::-;61663:16;61691:22;61716:19;61724:3;61716:7;:19::i;112878:187::-;112970:6;;;;112986:17;;;;;;;;;;;113018:40;;112970:6;;;112986:17;112970:6;;113018:40;;112951:16;;113018:40;112941:124;112878:187;:::o;47552:470::-;47652:16;;47707:19;:12;47652:16;47707;:19::i;:::-;47699:27;-1:-1:-1;32963:2:0;2670:26;16492:2;16488:16;;;16484:28;34217:37;47736:52;;;;-1:-1:-1;;;47736:52:0;;14136:2:1;47736:52:0;;;14118:21:1;14175:2;14155:18;;;14148:30;14214:20;14194:18;;;14187:48;14252:18;;47736:52:0;13934:342:1;47736:52:0;47809:115;47841:23;-1:-1:-1;;47841:21:0;;;:23::i;:::-;47878:36;:28;-1:-1:-1;;47878:26:0;;;:28::i;:36::-;47809:18;:115::i;:::-;47798:126;-1:-1:-1;47942:46:0;47952:25;-1:-1:-1;;47952:23:0;;;:25::i;:::-;52449:24;;52426:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;;;52342:152;47942:46;47934:81;;;;-1:-1:-1;;;47934:81:0;;14483:2:1;47934:81:0;;;14465:21:1;14522:2;14502:18;;;14495:30;14561:24;14541:18;;;14534:52;14603:18;;47934:81:0;14281:346:1;47934:81:0;47552:470;;;:::o;34358:143::-;34423:6;34455:38;-1:-1:-1;;34455:15:0;;34423:6;34491:1;34455:15;:38::i;34615:136::-;34679:6;34711:32;-1:-1:-1;;34711:15:0;;32857:1;;34711:15;:32::i;34844:124::-;34907:7;34933:28;-1:-1:-1;;34933:11:0;;32904:1;34958:2;34933:11;:28::i;35312:172::-;35380:7;35406:71;32963:2;35436:37;32963:2;16492;16488:16;;;2670:26;16484:28;35436:37;:::i;:::-;-1:-1:-1;;35406:11:0;;;:71;35475:1;35406:11;:71::i;56429:118::-;56496:7;56522:3;:11;;56534:5;56522:18;;;;;;;;:::i;:::-;;;;;;;;;56515:25;;56429:118;;;;:::o;111457:111::-;108411:13;;;;;;;108403:69;;;;-1:-1:-1;;;108403:69:0;;13724:2:1;108403:69:0;;;13706:21:1;13763:2;13743:18;;;13736:30;13802:34;13782:18;;;13775:62;13873:13;13853:18;;;13846:41;13904:19;;108403:69:0;13522:407:1;108403:69:0;111529:32:::1;110644:10:::0;111529:18:::1;:32::i;13655:359::-:0;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;:::-;13974:33;13655:359;-1:-1:-1;;;;;13655:359:0:o;10073:578::-;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;15129:31:1;10385:186:0;;;15117:44:1;15180:66;15284:3;15280:16;;;15276:25;;15262:12;;;15255:47;15332:15;15318:12;;;15311:37;15382:16;;;15378:25;15364:12;;;15357:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;15420:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;-1:-1:-1;;;10599:11:0;;;;;;;;:::i;10170:451::-;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;85090:164::-;85164:7;85190:57;81794:1;85217:5;85209:14;;;;;;;;:::i;:::-;:26;;;;:::i;:::-;-1:-1:-1;;85190:18:0;;;81794:1;85190:18;:57::i;84805:218::-;84946:7;84972:44;84987:5;84994:11;84987:5;84994:3;:11;:::i;:::-;-1:-1:-1;;84972:14:0;;;:44;85007:8;84972:14;:44::i;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;-1:-1:-1;;;20263:76:0;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;-1:-1:-1;;;20359:83:0;;16545:2:1;20359:83:0;;;16527:21:1;16584:2;16564:18;;;16557:30;16623:34;16603:18;;;16596:62;16694:28;16674:18;;;16667:56;16740:19;;20359:83:0;16343:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;27036:902::-;27114:15;-1:-1:-1;;7972:15:0;;;;27141:69;;;;-1:-1:-1;;;27141:69:0;;16972:2:1;27141:69:0;;;16954:21:1;17011:2;16991:18;;;16984:30;17050:34;17030:18;;;17023:62;17121:10;17101:18;;;17094:38;17149:19;;27141:69:0;16770:404:1;27141:69:0;27228:16;27236:7;27228;:16::i;:::-;27220:72;;;;-1:-1:-1;;;27220:72:0;;17381:2:1;27220:72:0;;;17363:21:1;17420:2;17400:18;;;17393:30;17459:34;17439:18;;;17432:62;17530:13;17510:18;;;17503:41;17561:19;;27220:72:0;17179:407:1;27220:72:0;27302:12;27317;27321:7;16492:2;16488:16;2670:26;16484:28;;16246:282;27317:12;27302:27;;;;27339:15;27357:12;27361:7;15386:3;15382:17;2670:26;15378:29;;15059:364;27357:12;27339:30;;;;27380:11;27501:4;27495:11;27488:18;;27588:7;27583:3;27580:16;27577:94;;;27628:4;27622;27615:18;27577:94;27843:4;27834:7;27828:4;27819:7;27816:1;27809:5;27798:50;27794:55;27879:52;27900:15;27907:7;14417:3;14413:17;;14206:268;27900:15;12061:27;12065:2;12061:27;;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;;11811:446;27879:52;27869:62;27036:902;-1:-1:-1;;;;;;27036:902:0:o;57087:109::-;57143:16;57178:3;:11;;57171:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57087:109;;;:::o;35074:155::-;35137:7;35163:59;-1:-1:-1;;35163:11:0;;35137:7;32963:2;35137:7;35163:11;:59::i;46716:285::-;46826:14;;46873;-1:-1:-1;;46873:12:0;;;:14::i;:::-;46856:31;;46906:36;46935:6;45309:58;;19348:66:1;45309:58:0;;;19336:79:1;19431:12;;;19424:28;;;45179:7:0;;19468:12:1;;45309:58:0;;;;;;;;;;;;45299:69;;;;;;45292:76;;45110:265;;;;46906:36;46897:45;;46961:33;46975:6;46983:10;46961:13;:33::i;17129:399::-;17268:7;17287:12;17302;17306:7;15386:3;15382:17;2670:26;15378:29;;15059:364;17302:12;17287:27;;;;17398:12;17402:7;17398:3;:12::i;:::-;17391:4;17375:13;17382:6;17375:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17371:77;;;-1:-1:-1;;17426:11:0;;;;;17371:77;17465:13;17472:6;17465:4;:13;:::i;:::-;17458:20;;17495:26;17501:7;17495:26;;17510:4;17516;12796:462;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;-1:-1:-1;;12065:2:0;12061:27;;;12135:17;;;;12127:26;;;12199:17;12195:2;12191:26;;12796:462::o;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19061:33;;;19244:1;19306;19386;19448;19130:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19104:391;;18926:576;;;;18761:741;;;;;;:::o;8645:333::-;8702:8;8726:15;8733:7;14417:3;14413:17;;14206:268;8726:15;:31;;8745:12;8726:31;8722:74;;-1:-1:-1;8780:5:0;;8645:333;-1:-1:-1;8645:333:0:o;8722:74::-;8805:12;8820;8824:7;8820:3;:12::i;:::-;8955:4;8949:11;-1:-1:-1;8936:26:0;;8645:333;-1:-1:-1;;;8645:333:0:o;41406:227::-;41484:7;41504:17;41523:18;41545:27;41556:4;41562:9;41545:10;:27::i;:::-;41503:69;;;;41582:18;41594:5;41582:11;:18::i;16702:147::-;16755:7;16820:12;16824:7;16492:2;16488:16;2670:26;16484:28;;16246:282;16820:12;16805;16809:7;15386:3;15382:17;2670:26;15378:29;;15059:364;16805:12;:27;16798:34;;;;16702:147;;;:::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;39341:1279::-;39422:7;39431:12;39652:9;:16;39672:2;39652:22;39648:966;;39941:4;39926:20;;39920:27;39990:4;39975:20;;39969:27;40047:4;40032:20;;40026:27;39690:9;40018:36;40088:25;40099:4;40018:36;39920:27;39969;40088:10;:25::i;:::-;40081:32;;;;;;;;;39648:966;40134:9;:16;40154:2;40134:22;40130:484;;40403:4;40388:20;;40382:27;40453:4;40438:20;;40432:27;40493:23;40504:4;40382:27;40432;40493:10;:23::i;:::-;40486:30;;;;;;;;40130:484;-1:-1:-1;40563:1:0;;-1:-1:-1;40567:35:0;40130:484;39341:1279;;;;;:::o;37646:631::-;37723:20;37714:5;:29;;;;;;;;:::i;:::-;;37710:561;;37646:631;:::o;37710:561::-;37819:29;37810:5;:38;;;;;;;;:::i;:::-;;37806:465;;37864:34;;-1:-1:-1;;;37864:34:0;;19693:2:1;37864:34:0;;;19675:21:1;19732:2;19712:18;;;19705:30;19771:26;19751:18;;;19744:54;19815:18;;37864:34:0;19491:348:1;37806:465:0;37928:35;37919:5;:44;;;;;;;;:::i;:::-;;37915:356;;37979:41;;-1:-1:-1;;;37979:41:0;;20046:2:1;37979:41:0;;;20028:21:1;20085:2;20065:18;;;20058:30;20124:33;20104:18;;;20097:61;20175:18;;37979:41:0;19844:355:1;37915:356:0;38050:30;38041:5;:39;;;;;;;;:::i;:::-;;38037:234;;38096:44;;-1:-1:-1;;;38096:44:0;;20406:2:1;38096:44:0;;;20388:21:1;20445:2;20425:18;;;20418:30;20484:34;20464:18;;;20457:62;20555:4;20535:18;;;20528:32;20577:19;;38096:44:0;20204:398:1;38037:234:0;38170:30;38161:5;:39;;;;;;;;:::i;:::-;;38157:114;;38216:44;;-1:-1:-1;;;38216:44:0;;20809:2:1;38216:44:0;;;20791:21:1;20848:2;20828:18;;;20821:30;20887:34;20867:18;;;20860:62;20958:4;20938:18;;;20931:32;20980:19;;38216:44:0;20607:398:1;2943:1393:0;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;42814:1603::-;42940:7;;43864:66;43851:79;;43847:161;;;-1:-1:-1;43962:1:0;;-1:-1:-1;43966:30:0;43946:51;;43847:161;44021:1;:7;;44026:2;44021:7;;:18;;;;;44032:1;:7;;44037:2;44032:7;;44021:18;44017:100;;;-1:-1:-1;44071:1:0;;-1:-1:-1;44075:30:0;44055:51;;44017:100;44228:24;;;44211:14;44228:24;;;;;;;;;21237:25:1;;;21310:4;21298:17;;21278:18;;;21271:45;;;;21332:18;;;21325:34;;;21375:18;;;21368:34;;;44228:24:0;;21209:19:1;;44228:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44228:24:0;;;;;;-1:-1:-1;;44266:20:0;;;44262:101;;44318:1;44322:29;44302:50;;;;;;;44262:101;44381:6;-1:-1:-1;44389:20:0;;-1:-1:-1;42814:1603:0;;;;;;;;:::o;41887:336::-;41997:7;;42055:66;42042:80;;41997:7;42148:25;42164:3;42149:18;;;42171:2;42148:25;:::i;:::-;42132:42;;42191:25;42202:4;42208:1;42211;42214;42191:10;:25::i;:::-;42184:32;;;;;;41887:336;;;;;;:::o;14:163:1:-;81:20;;141:10;130:22;;120:33;;110:61;;167:1;164;157:12;182:324;257:6;265;273;326:2;314:9;305:7;301:23;297:32;294:52;;;342:1;339;332:12;294:52;365:28;383:9;365:28;:::i;:::-;355:38;;412:37;445:2;434:9;430:18;412:37;:::i;:::-;402:47;;496:2;485:9;481:18;468:32;458:42;;182:324;;;;;:::o;885:184::-;937:77;934:1;927:88;1034:4;1031:1;1024:15;1058:4;1055:1;1048:15;1074:777;1116:5;1169:3;1162:4;1154:6;1150:17;1146:27;1136:55;;1187:1;1184;1177:12;1136:55;1223:6;1210:20;1249:18;1286:2;1282;1279:10;1276:36;;;1292:18;;:::i;:::-;1426:2;1420:9;1488:4;1480:13;;1331:66;1476:22;;;1500:2;1472:31;1468:40;1456:53;;;1524:18;;;1544:22;;;1521:46;1518:72;;;1570:18;;:::i;:::-;1610:10;1606:2;1599:22;1645:2;1637:6;1630:18;1691:3;1684:4;1679:2;1671:6;1667:15;1663:26;1660:35;1657:55;;;1708:1;1705;1698:12;1657:55;1772:2;1765:4;1757:6;1753:17;1746:4;1738:6;1734:17;1721:54;1819:1;1812:4;1807:2;1799:6;1795:15;1791:26;1784:37;1839:6;1830:15;;;;;;1074:777;;;;:::o;1856:609::-;1976:6;1984;1992;2000;2053:4;2041:9;2032:7;2028:23;2024:34;2021:54;;;2071:1;2068;2061:12;2021:54;2094:28;2112:9;2094:28;:::i;:::-;2084:38;;2173:2;2162:9;2158:18;2145:32;2200:18;2192:6;2189:30;2186:50;;;2232:1;2229;2222:12;2186:50;2255:49;2296:7;2287:6;2276:9;2272:22;2255:49;:::i;:::-;2245:59;;;2338:4;2327:9;2323:20;2362:7;2358:2;2355:15;2352:35;;;2383:1;2380;2373:12;2352:35;1856:609;;;;-1:-1:-1;;;2421:2:1;2406:18;;;;;2443:16;;;1856:609::o;2470:154::-;2556:42;2549:5;2545:54;2538:5;2535:65;2525:93;;2614:1;2611;2604:12;2629:319;2696:6;2704;2757:2;2745:9;2736:7;2732:23;2728:32;2725:52;;;2773:1;2770;2763:12;2725:52;2796:28;2814:9;2796:28;:::i;:::-;2786:38;;2874:2;2863:9;2859:18;2846:32;2887:31;2912:5;2887:31;:::i;:::-;2937:5;2927:15;;;2629:319;;;;;:::o;2953:180::-;3012:6;3065:2;3053:9;3044:7;3040:23;3036:32;3033:52;;;3081:1;3078;3071:12;3033:52;-1:-1:-1;3104:23:1;;2953:180;-1:-1:-1;2953:180:1:o;3369:252::-;3436:6;3444;3497:2;3485:9;3476:7;3472:23;3468:32;3465:52;;;3513:1;3510;3503:12;3465:52;3536:28;3554:9;3536:28;:::i;:::-;3526:38;3611:2;3596:18;;;;3583:32;;-1:-1:-1;;;3369:252:1:o;4005:320::-;4073:6;4126:2;4114:9;4105:7;4101:23;4097:32;4094:52;;;4142:1;4139;4132:12;4094:52;4182:9;4169:23;4215:18;4207:6;4204:30;4201:50;;;4247:1;4244;4237:12;4201:50;4270:49;4311:7;4302:6;4291:9;4287:22;4270:49;:::i;4330:320::-;4406:6;4414;4422;4475:2;4463:9;4454:7;4450:23;4446:32;4443:52;;;4491:1;4488;4481:12;4443:52;4514:28;4532:9;4514:28;:::i;:::-;4504:38;4589:2;4574:18;;4561:32;;-1:-1:-1;4640:2:1;4625:18;;;4612:32;;4330:320;-1:-1:-1;;;4330:320:1:o;4655:681::-;4826:2;4878:21;;;4948:13;;4851:18;;;4970:22;;;4797:4;;4826:2;5049:15;;;;5023:2;5008:18;;;4797:4;5092:218;5106:6;5103:1;5100:13;5092:218;;;5171:13;;5186:42;5167:62;5155:75;;5285:15;;;;5250:12;;;;5128:1;5121:9;5092:218;;;-1:-1:-1;5327:3:1;;4655:681;-1:-1:-1;;;;;;4655:681:1:o;5341:184::-;5399:6;5452:2;5440:9;5431:7;5427:23;5423:32;5420:52;;;5468:1;5465;5458:12;5420:52;5491:28;5509:9;5491:28;:::i;5530:272::-;5614:6;5667:2;5655:9;5646:7;5642:23;5638:32;5635:52;;;5683:1;5680;5673:12;5635:52;5722:9;5709:23;5741:31;5766:5;5741:31;:::i;6504:184::-;6556:77;6553:1;6546:88;6653:4;6650:1;6643:15;6677:4;6674:1;6667:15;6693:128;6733:3;6764:1;6760:6;6757:1;6754:13;6751:39;;;6770:18;;:::i;:::-;-1:-1:-1;6806:9:1;;6693:128::o;6826:184::-;6878:77;6875:1;6868:88;6975:4;6972:1;6965:15;6999:4;6996:1;6989:15;9980:530;10021:3;10059:5;10053:12;10086:6;10081:3;10074:19;10111:1;10121:162;10135:6;10132:1;10129:13;10121:162;;;10197:4;10253:13;;;10249:22;;10243:29;10225:11;;;10221:20;;10214:59;10150:12;10121:162;;;10301:6;10298:1;10295:13;10292:87;;;10367:1;10360:4;10351:6;10346:3;10342:16;10338:27;10331:38;10292:87;-1:-1:-1;10424:2:1;10412:15;10429:66;10408:88;10399:98;;;;10499:4;10395:109;;9980:530;-1:-1:-1;;9980:530:1:o;10515:547::-;10733:4;10762:10;10811:2;10803:6;10799:15;10788:9;10781:34;10863:2;10855:6;10851:15;10846:2;10835:9;10831:18;10824:43;;10903:6;10898:2;10887:9;10883:18;10876:34;10946:6;10941:2;10930:9;10926:18;10919:34;10990:3;10984;10973:9;10969:19;10962:32;11011:45;11051:3;11040:9;11036:19;11028:6;11011:45;:::i;:::-;11003:53;10515:547;-1:-1:-1;;;;;;;10515:547:1:o;12444:217::-;12591:2;12580:9;12573:21;12554:4;12611:44;12651:2;12640:9;12636:18;12628:6;12611:44;:::i;12666:184::-;12718:77;12715:1;12708:88;12815:4;12812:1;12805:15;12839:4;12836:1;12829:15;14632:125;14672:4;14700:1;14697;14694:8;14691:34;;;14705:18;;:::i;:::-;-1:-1:-1;14742:9:1;;14632:125::o;15667:228::-;15707:7;15833:1;15765:66;15761:74;15758:1;15755:81;15750:1;15743:9;15736:17;15732:105;15729:131;;;15840:18;;:::i;:::-;-1:-1:-1;15880:9:1;;15667:228::o;15900:195::-;15938:4;15975;15972:1;15968:12;16007:4;16004:1;16000:12;16032:3;16027;16024:12;16021:38;;;16039:18;;:::i;:::-;16076:13;;;15900:195;-1:-1:-1;;;15900:195:1:o;16100:238::-;16138:7;16178:4;16175:1;16171:12;16210:4;16207:1;16203:12;16270:3;16264:4;16260:14;16255:3;16252:23;16245:3;16238:11;16231:19;16227:49;16224:75;;;16279:18;;:::i;:::-;16319:13;;16100:238;-1:-1:-1;;;16100:238:1:o;17710:1391::-;18432:34;18420:47;;18497:23;18492:2;18483:12;;18476:45;18540:66;18644:3;18640:16;;;18636:25;;18631:2;18622:12;;18615:47;18681:17;18723:2;18714:12;;18707:24;;;18765:16;;;18761:25;;18756:2;18747:12;;18740:47;18817:34;18812:2;18803:12;;18796:56;18883:3;18877;18868:13;;18861:26;18922:16;;;18918:25;;18912:3;18903:13;;18896:48;18969:3;18960:13;;18953:25;19013:16;;;19009:25;19003:3;18994:13;;18987:48;17668:3;19090;19081:13;;17656:16;-1:-1:-1;17688:11:1;;;19051:44;17591:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"AttestationAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"Process","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"previousConfirmAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newConfirmAt","type":"uint256"}],"name":"SetConfirmation","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"acceptableRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"activeReplicaConfirmedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_messageId","type":"bytes32"}],"name":"activeReplicaMessageStatus","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"}],"name":"activeReplicaNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"process","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"prove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"proveAndProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"uint256","name":"_confirmAt","type":"uint256"}],"name":"setConfirmation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"submitAttestation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"events":{"Process(uint32,bytes32)":{"notice":"Emitted when message is processed"},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"notice":"Emitted when a root's confirmation is modified by governance"}},"kind":"user","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"notice":"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed"},"initialize(uint32,address)":{"notice":"Initialize the replica"},"process(bytes)":{"notice":"Given formatted message, attempts to dispatch message payload to end recipient."},"prove(uint32,bytes,bytes32[32],uint256)":{"notice":"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf."},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"notice":"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message."},"setConfirmation(uint32,bytes32,uint256)":{"notice":"Set confirmAt for a given root"},"setUpdater(uint32,address)":{"notice":"Set Updater role"},"submitAttestation(bytes)":{"notice":"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event."}},"version":1},"developerDoc":{"events":{"Process(uint32,bytes32)":{"params":{"messageHash":"The keccak256 hash of the message that was processed"}},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"params":{"newConfirmAt":"The new value of confirmAt","previousConfirmAt":"The previous value of confirmAt","root":"The root for which confirmAt has been set"}}},"kind":"dev","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"params":{"_root":"the Merkle root, submitted in an update, to check"},"returns":{"_0":"TRUE iff root has been submitted \u0026 timeout has expired"}},"initialize(uint32,address)":{"details":"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer","params":{"_remoteDomain":"The domain of the Home contract this follows","_updater":"The EVM id of the updater"}},"owner()":{"details":"Returns the address of the current owner."},"process(bytes)":{"details":"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.","params":{"_message":"Formatted message"}},"prove(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message","_proof":"Merkle proof of inclusion for leaf"},"returns":{"_0":"Returns true if proof was valid and `prove` call succeeded*"}},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if `prove` call returns false","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message (refer to Message library)","_proof":"Merkle proof of inclusion for message's leaf"}},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setConfirmation(uint32,bytes32,uint256)":{"details":"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)","params":{"_confirmAt":"The new confirmation time. Set to 0 to \"delete\" a root.","_root":"The root for which to modify confirm time"}},"setUpdater(uint32,address)":{"details":"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)","params":{"_updater":"New Updater"}},"submitAttestation(bytes)":{"details":"Reverts if update doesn't build off latest committedRoot or if signature is invalid.","params":{"_attestation":"Attestation data and signature"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"AttestationAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Process(uint32,bytes32)\":{\"params\":{\"messageHash\":\"The keccak256 hash of the message that was processed\"}},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"params\":{\"newConfirmAt\":\"The new value of confirmAt\",\"previousConfirmAt\":\"The previous value of confirmAt\",\"root\":\"The root for which confirmAt has been set\"}}},\"kind\":\"dev\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"params\":{\"_root\":\"the Merkle root, submitted in an update, to check\"},\"returns\":{\"_0\":\"TRUE iff root has been submitted \u0026 timeout has expired\"}},\"initialize(uint32,address)\":{\"details\":\"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer\",\"params\":{\"_remoteDomain\":\"The domain of the Home contract this follows\",\"_updater\":\"The EVM id of the updater\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"process(bytes)\":{\"details\":\"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.\",\"params\":{\"_message\":\"Formatted message\"}},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message\",\"_proof\":\"Merkle proof of inclusion for leaf\"},\"returns\":{\"_0\":\"Returns true if proof was valid and `prove` call succeeded*\"}},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if `prove` call returns false\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message (refer to Message library)\",\"_proof\":\"Merkle proof of inclusion for message's leaf\"}},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"details\":\"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)\",\"params\":{\"_confirmAt\":\"The new confirmation time. Set to 0 to \\\"delete\\\" a root.\",\"_root\":\"The root for which to modify confirm time\"}},\"setUpdater(uint32,address)\":{\"details\":\"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)\",\"params\":{\"_updater\":\"New Updater\"}},\"submitAttestation(bytes)\":{\"details\":\"Reverts if update doesn't build off latest committedRoot or if signature is invalid.\",\"params\":{\"_attestation\":\"Attestation data and signature\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"Process(uint32,bytes32)\":{\"notice\":\"Emitted when message is processed\"},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"notice\":\"Emitted when a root's confirmation is modified by governance\"}},\"kind\":\"user\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"notice\":\"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed\"},\"initialize(uint32,address)\":{\"notice\":\"Initialize the replica\"},\"process(bytes)\":{\"notice\":\"Given formatted message, attempts to dispatch message payload to end recipient.\"},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf.\"},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message.\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"notice\":\"Set confirmAt for a given root\"},\"setUpdater(uint32,address)\":{\"notice\":\"Set Updater role\"},\"submitAttestation(bytes)\":{\"notice\":\"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ReplicaManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74","acceptableRoot(uint32,uint32,bytes32)":"15a046aa","activeReplicaConfirmedAt(uint32,bytes32)":"7dfdba28","activeReplicaMessageStatus(uint32,bytes32)":"63415514","activeReplicaNonce(uint32)":"b65672d3","allGuards()":"9fe03fa2","getGuard(uint256)":"629ddf69","guardsAmount()":"246c2449","initialize(uint32,address)":"8624c35c","localDomain()":"8d3638f4","owner()":"8da5cb5b","process(bytes)":"928bc4b2","prove(uint32,bytes,bytes32[32],uint256)":"4f63be3f","proveAndProcess(uint32,bytes,bytes32[32],uint256)":"68705275","renounceOwnership()":"715018a6","setConfirmation(uint32,bytes32,uint256)":"9df7d36d","setSystemMessenger(address)":"b7bc563e","setUpdater(uint32,address)":"61bc3111","submitAttestation(bytes)":"f646a512","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManagerHarness.sol:ReplicaManagerHarness":{"code":"0x60a06040523480156200001157600080fd5b506040516200320338038062003203833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b6080516131676200009c60003960008181610335015281816109bd015261103e01526131676000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c80638d3638f4116100ee578063b7bc563e11610097578063e98fae1f11610071578063e98fae1f14610441578063f2fde38b14610454578063f646a51214610467578063ffa1ad741461047a57600080fd5b8063b7bc563e146103fb578063bfd84d361461040e578063ccbdf9c91461042157600080fd5b80639df7d36d116100c85780639df7d36d1461039d5780639fe03fa2146103b0578063b65672d3146103c557600080fd5b80638d3638f4146103305780638da5cb5b1461036c578063928bc4b21461038a57600080fd5b806361bc31111161015b578063687052751161013557806368705275146102c1578063715018a6146102d45780637dfdba28146102dc5780638624c35c1461031d57600080fd5b806361bc311114610235578063629ddf6914610248578063634155141461028057600080fd5b80632af678b01161018c5780632af678b0146101fa57806348639d241461020f5780634f63be3f1461022257600080fd5b8063089d2894146101b357806315a046aa146101cf578063246c2449146101f2575b600080fd5b6101bc60fd5481565b6040519081526020015b60405180910390f35b6101e26101dd366004612ad5565b610494565b60405190151581526020016101c6565b6101bc6104f1565b61020d610208366004612b33565b610502565b005b61020d61021d366004612b6a565b610511565b6101e2610230366004612c5d565b61051e565b61020d610243366004612b33565b610698565b61025b610256366004612b6a565b6106ff565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b6101bc61028e366004612ccd565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b61020d6102cf366004612c5d565b610712565b61020d610779565b6101bc6102ea366004612ccd565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b61020d61032b366004612b33565b6107e2565b6103577f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101c6565b60335473ffffffffffffffffffffffffffffffffffffffff1661025b565b61020d610398366004612cf7565b610964565b61020d6103ab366004612d2c565b610d02565b6103b8610df6565b6040516101c69190612d5f565b6103576103d3366004612db9565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b61020d610409366004612dd4565b610e02565b61020d61041c366004612d2c565b610eb0565b60655461025b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101e261044f366004612b33565b610ee1565b61020d610462366004612dd4565b610f1f565b61020d610475366004612cf7565b61101b565b610482600081565b60405160ff90911681526020016101c6565b63ffffffff8316600090815260ce6020908152604080832054835260cd82528083208484526001019091528120548082036104d35760009150506104ea565b6104e363ffffffff851682612e20565b4210159150505b9392505050565b60006104fd60986111f6565b905090565b61050c8282611200565b505050565b6105196112fd565b60fd55565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff16600281111561056d5761056d612e38565b146105bf5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561061d5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016105b6565b60006106538387602080602002604051908101604052809291908260208002808284376000920191909152508991506113649050565b600081815260018401602052604090205490915015610688576000928352600291909101602052604090912055506001610690565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146105025760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b600061070c60988361141e565b92915050565b61071e8484848461051e565b61076a5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016105b6565b61077383610964565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107e05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b565b60006107ee600161142a565b9050801561082357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61082b611581565b6108358383611200565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556108e78360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561050c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b600061096f82611606565b9050600061098262ffffff198316611614565b9050600061099562ffffff198316611654565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f0000000000000000000000000000000000000000000000000000000000000000166109ec62ffffff19851661167e565b63ffffffff1614610a3f5760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016105b6565b6000610a5062ffffff19861661169f565b6000818152600284016020526040902054909150610a6d816116fc565b610ab95760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016105b6565b610ad284610acc62ffffff198816611710565b83610494565b610b1e5760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016105b6565b60cb5460ff16600114610b735760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016105b6565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610bb2610bad62ffffff198816611731565b611768565b6000828152600284016020526040812060019055610bdd610bd862ffffff198816611800565b611821565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610c0b62ffffff198a16611863565b610c1a62ffffff198b16611884565b600087815260018a016020526040902054610c48610c3d62ffffff198f166118a5565b62ffffff19166118e4565b6040518663ffffffff1660e01b8152600401610c68959493929190612ed2565b600060405180830381600087803b158015610c8257600080fd5b505af1158015610c96573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610dac9083908690869061193716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60606104fd609861194b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b63ffffffff808416600090815260ce6020908152604080832054835260cd909152902061050c918490849061140a16565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415156104ea565b60335473ffffffffffffffffffffffffffffffffffffffff163314610f865760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b73ffffffffffffffffffffffffffffffffffffffff811661100f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105b6565b61101881611958565b50565b6000611026826119cf565b915050600061103a8262ffffff1916611b09565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16036110b75760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016105b6565b60006110c862ffffff198416611b1d565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116111435760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016105b6565b600061115462ffffff198616611b31565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6111d9610c3d8a62ffffff1916611b46565b6040516111e69190612f12565b60405180910390a4505050505050565b600061070c825490565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156112445750600061070c565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146107e05760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e6765720000000000000000000000000000000060448201526064016105b6565b8260005b602081101561140257600183821c16600085836020811061138b5761138b612f25565b60200201519050816001036113cb5760408051602081018390529081018590526060016040516020818303038152906040528051906020012093506113f8565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611368565b509392505050565b600091825260029092016020526040902055565b60006104ea8383611b79565b60008054610100900460ff16156114c7578160ff16600114801561144d5750303b155b6114bf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105b6565b506000919050565b60005460ff8084169116106115445760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105b6565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166115fe5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105b6565b6107e0611ba3565b600061070c82610539611c29565b60008161162962ffffff198216610539611c4d565b5061164b83611639856001611d4e565b611644866002611d4e565b6001611d80565b91505b50919050565b60008161166a60015b62ffffff19831690611c4d565b5061164b62ffffff19841660026004611d9f565b60008161168b600161165d565b5061164b62ffffff198416602a6004611d9f565b6000806116ba8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006116e48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b6000811580159061070c5750506001141590565b60008161171d600161165d565b5061164b62ffffff198416604e6004611d9f565b60008161174662ffffff198216610539611c4d565b5061164b83611756856002611d4e565b611761866003611d4e565b6002611d80565b7f1dad5ea7bf29006ead0af41296d42c169129acd1ec64b3639ebe94b8c01bfa1161179862ffffff198316611dcf565b6117a762ffffff198416611dfd565b6117b662ffffff198516611e1e565b6117c562ffffff198616611e3f565b604080516bffffffffffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190a150565b60008161180d600161165d565b5061164b62ffffff198416602e6020611e60565b600074010000000000000000000000000000000000000000820161185d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b8161070c565b600081611870600161165d565b5061164b62ffffff19841660266004611d9f565b600081611891600161165d565b5061164b62ffffff19841660066020611e60565b6000816118ba62ffffff198216610539611c4d565b5061164b836118ca856003611d4e565b601886901c6bffffffffffffffffffffffff166003611d80565b60606000806119018460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506040519150819250611926848360200161201e565b508181016020016040529052919050565b600091825260019092016020526040902055565b606060006104ea836121c3565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806119dc8382611c29565b905060286bffffffffffffffffffffffff601883901c1611611a405760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016105b6565b611a69611a5262ffffff19831661221f565b611a64610c3d62ffffff198516611b46565b612234565b9150611ab8611a7d62ffffff198316611b09565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b611b045760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f746172790000000000000000000060448201526064016105b6565b915091565b600061070c62ffffff198316826004611d9f565b600061070c62ffffff198316600480611d9f565b600061070c62ffffff19831660086020611e60565b600061070c6028611b6981601886901c6bffffffffffffffffffffffff16612f54565b62ffffff198516919060006122ab565b6000826000018281548110611b9057611b90612f25565b9060005260206000200154905092915050565b600054610100900460ff16611c205760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105b6565b6107e033611958565b815160009060208401611c4464ffffffffff85168284612321565b95945050505050565b6000611c598383612368565b611d47576000611c78611c6c8560d81c90565b64ffffffffff1661238b565b9150506000611c8d8464ffffffffff1661238b565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016105b69190612f12565b5090919050565b60006104ea6002836004811115611d6757611d67612e38565b611d719190612f6b565b62ffffff198516906002611d9f565b6000611c4484611d908186612f54565b62ffffff1988169190856122ab565b6000611dac826020612fa8565b611db7906008612fcb565b60ff16611dc5858585611e60565b901c949350505050565b600081611ddc600261165d565b50611df062ffffff1984166002600c611d9f565b63ffffffff169392505050565b600081611e0a600261165d565b50611df062ffffff198416600e600c611d9f565b600081611e2b600261165d565b50611df062ffffff198416601a600c611d9f565b600081611e4c600261165d565b50611df062ffffff1984166026600c611d9f565b60008160ff16600003611e75575060006104ea565b611e8d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611ea860ff841685612e20565b1115611f2057611f07611ec98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611eef8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16612475565b60405162461bcd60e51b81526004016105b69190612f12565b60208260ff161115611f9a5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016105b6565b600882026000611fb88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff198084160361209b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016105b6565b6120a4836124e3565b6121165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016105b6565b60006121308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061215a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561217f5760206060fd5b8285848460045afa506121b96121958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561221357602002820191906000526020600020905b8154815260200190600101908083116121ff575b50505050509050919050565b600061070c62ffffff198316826028816122ab565b60008061224662ffffff19851661169f565b905061229f816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506106908184612520565b6000806122c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506122df8661253c565b846122ea8784612e20565b6122f49190612e20565b11156123075762ffffff19915050610690565b6123118582612e20565b90506121b98364ffffffffff1682865b60008061232e8385612e20565b905060405181111561233e575060005b806000036123535762ffffff199150506104ea565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff1661237c8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156123fe5760006123aa826008612fcb565b60ff1685901c90506123bb81612584565b61ffff16841793508160ff166010146123d657601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612391565b50600f5b60ff8160ff16101561246f57600061241b826008612fcb565b60ff1685901c905061242c81612584565b61ffff16831792508160ff1660001461244757601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612402565b50915091565b606060006124828661238b565b91505060006124908661238b565b915050600061249e8661238b565b91505060006124ac8661238b565b915050838383836040516020016124c69493929190612ff4565b604051602081830303815290604052945050505050949350505050565b60006124ef8260d81c90565b64ffffffffff1664ffffffffff0361250957506000919050565b60006125148361253c565b60405110199392505050565b600080600061252f85856125b6565b9150915061140281612624565b60006125568260181c6bffffffffffffffffffffffff1690565b61256e8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061259660048360ff16901c612810565b60ff1661ffff919091161760081b6125ad82612810565b60ff1617919050565b60008082516041036125ec5760208301516040840151606085015160001a6125e087828585612957565b9450945050505061261d565b8251604003612615576020830151604084015161260a868383612a6f565b93509350505061261d565b506000905060025b9250929050565b600081600481111561263857612638612e38565b036126405750565b600181600481111561265457612654612e38565b036126a15760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105b6565b60028160048111156126b5576126b5612e38565b036127025760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105b6565b600381600481111561271657612716612e38565b036127895760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105b6565b600481600481111561279d5761279d612e38565b036110185760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105b6565b600060f08083179060ff8216900361282b5750603092915050565b8060ff1660f10361283f5750603192915050565b8060ff1660f2036128535750603292915050565b8060ff1660f3036128675750603392915050565b8060ff1660f40361287b5750603492915050565b8060ff1660f50361288f5750603592915050565b8060ff1660f6036128a35750603692915050565b8060ff1660f7036128b75750603792915050565b8060ff1660f8036128cb5750603892915050565b8060ff1660f9036128df5750603992915050565b8060ff1660fa036128f35750606192915050565b8060ff1660fb036129075750606292915050565b8060ff1660fc0361291b5750606392915050565b8060ff1660fd0361292f5750606492915050565b8060ff1660fe036129435750606592915050565b8060ff1660ff0361164e5750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561298e5750600090506003612a66565b8460ff16601b141580156129a657508460ff16601c14155b156129b75750600090506004612a66565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612a0b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a5f57600060019250925050612a66565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612aa560ff86901c601b612e20565b9050612ab387828885612957565b935093505050935093915050565b803563ffffffff8116811461157c57600080fd5b600080600060608486031215612aea57600080fd5b612af384612ac1565b9250612b0160208501612ac1565b9150604084013590509250925092565b73ffffffffffffffffffffffffffffffffffffffff8116811461101857600080fd5b60008060408385031215612b4657600080fd5b612b4f83612ac1565b91506020830135612b5f81612b11565b809150509250929050565b600060208284031215612b7c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612bc357600080fd5b813567ffffffffffffffff80821115612bde57612bde612b83565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612c2457612c24612b83565b81604052838152866020858801011115612c3d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806104608587031215612c7457600080fd5b612c7d85612ac1565b9350602085013567ffffffffffffffff811115612c9957600080fd5b612ca587828801612bb2565b935050610440850186811115612cba57600080fd5b9396929550505060409290920191903590565b60008060408385031215612ce057600080fd5b612ce983612ac1565b946020939093013593505050565b600060208284031215612d0957600080fd5b813567ffffffffffffffff811115612d2057600080fd5b61069084828501612bb2565b600080600060608486031215612d4157600080fd5b612d4a84612ac1565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612dad57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d7b565b50909695505050505050565b600060208284031215612dcb57600080fd5b6104ea82612ac1565b600060208284031215612de657600080fd5b81356104ea81612b11565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612e3357612e33612df1565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612e8d57602081850181015186830182015201612e71565b81811115612e9f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612f0760a0830184612e67565b979650505050505050565b6020815260006104ea6020830184612e67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612f6657612f66612df1565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612fa357612fa3612df1565b500290565b600060ff821660ff841680821015612fc257612fc2612df1565b90039392505050565b600060ff821660ff84168160ff0481118215151615612fec57612fec612df1565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016121b956fea264697066735822122077912efc3717025575bd9990ab6b1c994564411fcd37e67822c74bd01e33dc7664736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106101ae5760003560e01c80638d3638f4116100ee578063b7bc563e11610097578063e98fae1f11610071578063e98fae1f14610441578063f2fde38b14610454578063f646a51214610467578063ffa1ad741461047a57600080fd5b8063b7bc563e146103fb578063bfd84d361461040e578063ccbdf9c91461042157600080fd5b80639df7d36d116100c85780639df7d36d1461039d5780639fe03fa2146103b0578063b65672d3146103c557600080fd5b80638d3638f4146103305780638da5cb5b1461036c578063928bc4b21461038a57600080fd5b806361bc31111161015b578063687052751161013557806368705275146102c1578063715018a6146102d45780637dfdba28146102dc5780638624c35c1461031d57600080fd5b806361bc311114610235578063629ddf6914610248578063634155141461028057600080fd5b80632af678b01161018c5780632af678b0146101fa57806348639d241461020f5780634f63be3f1461022257600080fd5b8063089d2894146101b357806315a046aa146101cf578063246c2449146101f2575b600080fd5b6101bc60fd5481565b6040519081526020015b60405180910390f35b6101e26101dd366004612ad5565b610494565b60405190151581526020016101c6565b6101bc6104f1565b61020d610208366004612b33565b610502565b005b61020d61021d366004612b6a565b610511565b6101e2610230366004612c5d565b61051e565b61020d610243366004612b33565b610698565b61025b610256366004612b6a565b6106ff565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b6101bc61028e366004612ccd565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260029093019052205490565b61020d6102cf366004612c5d565b610712565b61020d610779565b6101bc6102ea366004612ccd565b63ffffffff91909116600090815260ce6020908152604080832054835260cd825280832093835260019093019052205490565b61020d61032b366004612b33565b6107e2565b6103577f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101c6565b60335473ffffffffffffffffffffffffffffffffffffffff1661025b565b61020d610398366004612cf7565b610964565b61020d6103ab366004612d2c565b610d02565b6103b8610df6565b6040516101c69190612d5f565b6103576103d3366004612db9565b63ffffffff908116600090815260ce6020908152604080832054835260cd9091529020541690565b61020d610409366004612dd4565b610e02565b61020d61041c366004612d2c565b610eb0565b60655461025b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101e261044f366004612b33565b610ee1565b61020d610462366004612dd4565b610f1f565b61020d610475366004612cf7565b61101b565b610482600081565b60405160ff90911681526020016101c6565b63ffffffff8316600090815260ce6020908152604080832054835260cd82528083208484526001019091528120548082036104d35760009150506104ea565b6104e363ffffffff851682612e20565b4210159150505b9392505050565b60006104fd60986111f6565b905090565b61050c8282611200565b505050565b6105196112fd565b60fd55565b825160208085019190912063ffffffff8616600090815260ce8352604080822054825260cd9093529182206001815468010000000000000000900460ff16600281111561056d5761056d612e38565b146105bf5760405162461bcd60e51b815260206004820152601260248201527f5265706c696361206e6f7420616374697665000000000000000000000000000060448201526064015b60405180910390fd5b60008281526002820160205260409020541561061d5760405162461bcd60e51b815260206004820152601360248201527f214d6573736167655374617475732e4e6f6e650000000000000000000000000060448201526064016105b6565b60006106538387602080602002604051908101604052809291908260208002808284376000920191909152508991506113649050565b600081815260018401602052604090205490915015610688576000928352600291909101602052604090912055506001610690565b600093505050505b949350505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146105025760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b600061070c60988361141e565b92915050565b61071e8484848461051e565b61076a5760405162461bcd60e51b815260206004820152600660248201527f2170726f7665000000000000000000000000000000000000000000000000000060448201526064016105b6565b61077383610964565b50505050565b60335473ffffffffffffffffffffffffffffffffffffffff1633146107e05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b565b60006107ee600161142a565b9050801561082357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61082b611581565b6108358383611200565b5060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556108e78360cc54600101600081815260cd60205260409020805463ffffffff8416640100000000027fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffff0000000000ffffffff909116176801000000000000000017905560cc819055919050565b63ffffffff8416600090815260ce6020526040902055801561050c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050565b600061096f82611606565b9050600061098262ffffff198316611614565b9050600061099562ffffff198316611654565b63ffffffff808216600090815260ce6020908152604080832054835260cd90915290209192507f0000000000000000000000000000000000000000000000000000000000000000166109ec62ffffff19851661167e565b63ffffffff1614610a3f5760405162461bcd60e51b815260206004820152600c60248201527f2164657374696e6174696f6e000000000000000000000000000000000000000060448201526064016105b6565b6000610a5062ffffff19861661169f565b6000818152600284016020526040902054909150610a6d816116fc565b610ab95760405162461bcd60e51b815260206004820152601460248201527f21657869737473207c7c2070726f63657373656400000000000000000000000060448201526064016105b6565b610ad284610acc62ffffff198816611710565b83610494565b610b1e5760405162461bcd60e51b815260206004820152601260248201527f216f7074696d69737469635365636f6e6473000000000000000000000000000060448201526064016105b6565b60cb5460ff16600114610b735760405162461bcd60e51b815260206004820152600a60248201527f217265656e7472616e740000000000000000000000000000000000000000000060448201526064016105b6565b60cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610bb2610bad62ffffff198816611731565b611768565b6000828152600284016020526040812060019055610bdd610bd862ffffff198816611800565b611821565b905073ffffffffffffffffffffffffffffffffffffffff811663e4d16d6286610c0b62ffffff198a16611863565b610c1a62ffffff198b16611884565b600087815260018a016020526040902054610c48610c3d62ffffff198f166118a5565b62ffffff19166118e4565b6040518663ffffffff1660e01b8152600401610c68959493929190612ed2565b600060405180830381600087803b158015610c8257600080fd5b505af1158015610c96573d6000803e3d6000fd5b505060405185925063ffffffff881691507f321b81f91f333e67baf2913d8e645ce8e6106353305e49ff6e02e5110aea84af90600090a3505060cb80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b63ffffffff808416600090815260ce6020908152604080832054835260cd825280832086845260018101909252909120549091610dac9083908690869061193716565b6040805182815260208101859052859163ffffffff8816917f6dc81ebe3eada4cb187322470457db45b05b451f739729cfa5789316e9722730910160405180910390a35050505050565b60606104fd609861194b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e695760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b606580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b63ffffffff808416600090815260ce6020908152604080832054835260cd909152902061050c918490849061140a16565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205415156104ea565b60335473ffffffffffffffffffffffffffffffffffffffff163314610f865760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105b6565b73ffffffffffffffffffffffffffffffffffffffff811661100f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016105b6565b61101881611958565b50565b6000611026826119cf565b915050600061103a8262ffffff1916611b09565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff168163ffffffff16036110b75760405162461bcd60e51b815260206004820152601c60248201527f5570646174652072656665727320746f206c6f63616c20636861696e0000000060448201526064016105b6565b60006110c862ffffff198416611b1d565b63ffffffff808416600090815260ce6020908152604080832054835260cd90915290208054929350918116908316116111435760405162461bcd60e51b815260206004820152601f60248201527f557064617465206f6c646572207468616e2063757272656e742073746174650060448201526064016105b6565b600061115462ffffff198616611b31565b60008181526001840160205260409020429055905081547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff8416178255808363ffffffff168563ffffffff167f04da455c16eefb6eedafa9196d9ec3227b75b5f7e9a9727650a18cdae99393cb6111d9610c3d8a62ffffff1916611b46565b6040516111e69190612f12565b60405180910390a4505050505050565b600061070c825490565b63ffffffff8216600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152812054156112445750600061070c565b63ffffffff8316600081815260666020908152604080832080546001810182558185528385200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff891690811790915585855290546067845282852082865284529382902093909355519182527f62d8d15324cce2626119bb61d595f59e655486b1ab41b52c0793d814fe03c355910160405180910390a250600192915050565b60655473ffffffffffffffffffffffffffffffffffffffff1633146107e05760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e6765720000000000000000000000000000000060448201526064016105b6565b8260005b602081101561140257600183821c16600085836020811061138b5761138b612f25565b60200201519050816001036113cb5760408051602081018390529081018590526060016040516020818303038152906040528051906020012093506113f8565b60408051602081018690529081018290526060016040516020818303038152906040528051906020012093505b5050600101611368565b509392505050565b600091825260029092016020526040902055565b60006104ea8383611b79565b60008054610100900460ff16156114c7578160ff16600114801561144d5750303b155b6114bf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105b6565b506000919050565b60005460ff8084169116106115445760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016105b6565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b919050565b600054610100900460ff166115fe5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105b6565b6107e0611ba3565b600061070c82610539611c29565b60008161162962ffffff198216610539611c4d565b5061164b83611639856001611d4e565b611644866002611d4e565b6001611d80565b91505b50919050565b60008161166a60015b62ffffff19831690611c4d565b5061164b62ffffff19841660026004611d9f565b60008161168b600161165d565b5061164b62ffffff198416602a6004611d9f565b6000806116ba8360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006116e48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b6000811580159061070c5750506001141590565b60008161171d600161165d565b5061164b62ffffff198416604e6004611d9f565b60008161174662ffffff198216610539611c4d565b5061164b83611756856002611d4e565b611761866003611d4e565b6002611d80565b7f1dad5ea7bf29006ead0af41296d42c169129acd1ec64b3639ebe94b8c01bfa1161179862ffffff198316611dcf565b6117a762ffffff198416611dfd565b6117b662ffffff198516611e1e565b6117c562ffffff198616611e3f565b604080516bffffffffffffffffffffffff9586168152938516602085015291841683830152909216606082015290519081900360800190a150565b60008161180d600161165d565b5061164b62ffffff198416602e6020611e60565b600074010000000000000000000000000000000000000000820161185d57505060655473ffffffffffffffffffffffffffffffffffffffff1690565b8161070c565b600081611870600161165d565b5061164b62ffffff19841660266004611d9f565b600081611891600161165d565b5061164b62ffffff19841660066020611e60565b6000816118ba62ffffff198216610539611c4d565b5061164b836118ca856003611d4e565b601886901c6bffffffffffffffffffffffff166003611d80565b60606000806119018460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506040519150819250611926848360200161201e565b508181016020016040529052919050565b600091825260019092016020526040902055565b606060006104ea836121c3565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000806119dc8382611c29565b905060286bffffffffffffffffffffffff601883901c1611611a405760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e000000000000000000000000000060448201526064016105b6565b611a69611a5262ffffff19831661221f565b611a64610c3d62ffffff198516611b46565b612234565b9150611ab8611a7d62ffffff198316611b09565b63ffffffff16600090815260676020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152902054151590565b611b045760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f746172790000000000000000000060448201526064016105b6565b915091565b600061070c62ffffff198316826004611d9f565b600061070c62ffffff198316600480611d9f565b600061070c62ffffff19831660086020611e60565b600061070c6028611b6981601886901c6bffffffffffffffffffffffff16612f54565b62ffffff198516919060006122ab565b6000826000018281548110611b9057611b90612f25565b9060005260206000200154905092915050565b600054610100900460ff16611c205760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105b6565b6107e033611958565b815160009060208401611c4464ffffffffff85168284612321565b95945050505050565b6000611c598383612368565b611d47576000611c78611c6c8560d81c90565b64ffffffffff1661238b565b9150506000611c8d8464ffffffffff1661238b565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b81526004016105b69190612f12565b5090919050565b60006104ea6002836004811115611d6757611d67612e38565b611d719190612f6b565b62ffffff198516906002611d9f565b6000611c4484611d908186612f54565b62ffffff1988169190856122ab565b6000611dac826020612fa8565b611db7906008612fcb565b60ff16611dc5858585611e60565b901c949350505050565b600081611ddc600261165d565b50611df062ffffff1984166002600c611d9f565b63ffffffff169392505050565b600081611e0a600261165d565b50611df062ffffff198416600e600c611d9f565b600081611e2b600261165d565b50611df062ffffff198416601a600c611d9f565b600081611e4c600261165d565b50611df062ffffff1984166026600c611d9f565b60008160ff16600003611e75575060006104ea565b611e8d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611ea860ff841685612e20565b1115611f2057611f07611ec98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16611eef8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff16612475565b60405162461bcd60e51b81526004016105b69190612f12565b60208260ff161115611f9a5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e20333220627974657300000000000060648201526084016105b6565b600882026000611fb88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b600062ffffff198084160361209b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f657220646572656600000000000000000000000000000000000000000000000060648201526084016105b6565b6120a4836124e3565b6121165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e74657220646572656600000000000000000000000000000000000000000060648201526084016105b6565b60006121308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061215a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561217f5760206060fd5b8285848460045afa506121b96121958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b9695505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561221357602002820191906000526020600020905b8154815260200190600101908083116121ff575b50505050509050919050565b600061070c62ffffff198316826028816122ab565b60008061224662ffffff19851661169f565b905061229f816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506106908184612520565b6000806122c68660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506122df8661253c565b846122ea8784612e20565b6122f49190612e20565b11156123075762ffffff19915050610690565b6123118582612e20565b90506121b98364ffffffffff1682865b60008061232e8385612e20565b905060405181111561233e575060005b806000036123535762ffffff199150506104ea565b5050606092831b9190911790911b1760181b90565b60008164ffffffffff1661237c8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156123fe5760006123aa826008612fcb565b60ff1685901c90506123bb81612584565b61ffff16841793508160ff166010146123d657601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612391565b50600f5b60ff8160ff16101561246f57600061241b826008612fcb565b60ff1685901c905061242c81612584565b61ffff16831792508160ff1660001461244757601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612402565b50915091565b606060006124828661238b565b91505060006124908661238b565b915050600061249e8661238b565b91505060006124ac8661238b565b915050838383836040516020016124c69493929190612ff4565b604051602081830303815290604052945050505050949350505050565b60006124ef8260d81c90565b64ffffffffff1664ffffffffff0361250957506000919050565b60006125148361253c565b60405110199392505050565b600080600061252f85856125b6565b9150915061140281612624565b60006125568260181c6bffffffffffffffffffffffff1690565b61256e8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061259660048360ff16901c612810565b60ff1661ffff919091161760081b6125ad82612810565b60ff1617919050565b60008082516041036125ec5760208301516040840151606085015160001a6125e087828585612957565b9450945050505061261d565b8251604003612615576020830151604084015161260a868383612a6f565b93509350505061261d565b506000905060025b9250929050565b600081600481111561263857612638612e38565b036126405750565b600181600481111561265457612654612e38565b036126a15760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105b6565b60028160048111156126b5576126b5612e38565b036127025760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105b6565b600381600481111561271657612716612e38565b036127895760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105b6565b600481600481111561279d5761279d612e38565b036110185760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105b6565b600060f08083179060ff8216900361282b5750603092915050565b8060ff1660f10361283f5750603192915050565b8060ff1660f2036128535750603292915050565b8060ff1660f3036128675750603392915050565b8060ff1660f40361287b5750603492915050565b8060ff1660f50361288f5750603592915050565b8060ff1660f6036128a35750603692915050565b8060ff1660f7036128b75750603792915050565b8060ff1660f8036128cb5750603892915050565b8060ff1660f9036128df5750603992915050565b8060ff1660fa036128f35750606192915050565b8060ff1660fb036129075750606292915050565b8060ff1660fc0361291b5750606392915050565b8060ff1660fd0361292f5750606492915050565b8060ff1660fe036129435750606592915050565b8060ff1660ff0361164e5750606692915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561298e5750600090506003612a66565b8460ff16601b141580156129a657508460ff16601c14155b156129b75750600090506004612a66565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612a0b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612a5f57600060019250925050612a66565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612aa560ff86901c601b612e20565b9050612ab387828885612957565b935093505050935093915050565b803563ffffffff8116811461157c57600080fd5b600080600060608486031215612aea57600080fd5b612af384612ac1565b9250612b0160208501612ac1565b9150604084013590509250925092565b73ffffffffffffffffffffffffffffffffffffffff8116811461101857600080fd5b60008060408385031215612b4657600080fd5b612b4f83612ac1565b91506020830135612b5f81612b11565b809150509250929050565b600060208284031215612b7c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612bc357600080fd5b813567ffffffffffffffff80821115612bde57612bde612b83565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612c2457612c24612b83565b81604052838152866020858801011115612c3d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806104608587031215612c7457600080fd5b612c7d85612ac1565b9350602085013567ffffffffffffffff811115612c9957600080fd5b612ca587828801612bb2565b935050610440850186811115612cba57600080fd5b9396929550505060409290920191903590565b60008060408385031215612ce057600080fd5b612ce983612ac1565b946020939093013593505050565b600060208284031215612d0957600080fd5b813567ffffffffffffffff811115612d2057600080fd5b61069084828501612bb2565b600080600060608486031215612d4157600080fd5b612d4a84612ac1565b95602085013595506040909401359392505050565b6020808252825182820181905260009190848201906040850190845b81811015612dad57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d7b565b50909695505050505050565b600060208284031215612dcb57600080fd5b6104ea82612ac1565b600060208284031215612de657600080fd5b81356104ea81612b11565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115612e3357612e33612df1565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000815180845260005b81811015612e8d57602081850181015186830182015201612e71565b81811115612e9f576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600063ffffffff808816835280871660208401525084604083015283606083015260a06080830152612f0760a0830184612e67565b979650505050505050565b6020815260006104ea6020830184612e67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082821015612f6657612f66612df1565b500390565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612fa357612fa3612df1565b500290565b600060ff821660ff841680821015612fc257612fc2612df1565b90039392505050565b600060ff821660ff84168160ff0481118215151615612fec57612fec612df1565b029392505050565b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016121b956fea264697066735822122077912efc3717025575bd9990ab6b1c994564411fcd37e67822c74bd01e33dc7664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"131226:1155:0:-:0;;;131488:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;115172:26;;;;131226:1155;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;131226:1155:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"131226:1155:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;131327:29;;;;;;;;;160:25:1;;;148:2;133:18;131327:29:0;;;;;;;;127486:361;;;;;;:::i;:::-;;:::i;:::-;;;858:14:1;;851:22;833:41;;821:2;806:18;127486:361:0;693:187:1;66914:95:0;;;:::i;131558:104::-;;;;;;:::i;:::-;;:::i;:::-;;131803:118;;;;;;:::i;:::-;;:::i;128509:1028::-;;;;;;:::i;:::-;;:::i;126187:158::-;;;;;;:::i;:::-;;:::i;66801:107::-;;;;;;:::i;:::-;;:::i;:::-;;;3314:42:1;3302:55;;;3284:74;;3272:2;3257:18;66801:107:0;3138:226:1;121819:230:0;;;;;;:::i;:::-;121986:29;;;;;121944:7;121986:29;;;:14;:29;;;;;;;;;121974:42;;:11;:42;;;;;:68;;;:56;;;;:68;;;;;121819:230;123772:271;;;;;;:::i;:::-;;:::i;117488:57::-;;;:::i;121599:214::-;;;;;;:::i;:::-;121759:29;;;;;121717:7;121759:29;;;:14;:29;;;;;;;;;121747:42;;:11;:42;;;;;:59;;;:52;;;;:59;;;;;121599:214;121084:295;;;;;;:::i;:::-;;:::i;113961:35::-;;;;;;;;3982:10:1;3970:23;;;3952:42;;3940:2;3925:18;113961:35:0;3808:192:1;111644:85:0;111716:6;;;;111644:85;;124481:1415;;;;;;:::i;:::-;;:::i;126696:423::-;;;;;;:::i;:::-;;:::i;66694:101::-;;;:::i;:::-;;;;;;;:::i;121440:153::-;;;;;;:::i;:::-;121550:29;;;;121513:6;121550:29;;;:14;:29;;;;;;;;;121538:42;;:11;:42;;;;;:48;;;121440:153;117162:133;;;;;;:::i;:::-;;:::i;131927:225::-;;;;;;:::i;:::-;;:::i;114543:39::-;;;;;;;;;131668:129;;;;;;:::i;:::-;;:::i;112526:198::-;;;;;;:::i;:::-;;:::i;122539:801::-;;;;;;:::i;:::-;;:::i;68110:33::-;;68142:1;68110:33;;;;;6812:4:1;6800:17;;;6782:36;;6770:2;6755:18;68110:33:0;6640:184:1;127486:361:0;127669:29;;;127625:4;127669:29;;;:14;:29;;;;;;;;;127657:42;;:11;:42;;;;;:59;;;:52;;:59;;;;;;127730:10;;;127726:53;;127763:5;127756:12;;;;;127726:53;127814:26;;;;:5;:26;:::i;:::-;127795:15;:45;;127788:52;;;127486:361;;;;;;:::o;66914:95::-;66961:7;66987:15;:6;:13;:15::i;:::-;66980:22;;66914:95;:::o;131558:104::-;131627:28;131638:7;131647;131627:10;:28::i;:::-;;131558:104;;:::o;131803:118::-;116574:24;:22;:24::i;:::-;131888:14:::1;:26:::0;131803:118::o;128509:1028::-;128700:19;;;;;;;;;;128778:29;;;128668:4;128778:29;;;:14;:29;;;;;;;128766:42;;:11;:42;;;;;;128885:31;128867:14;;;;;;;:49;;;;;;;;:::i;:::-;;128859:80;;;;-1:-1:-1;;;128859:80:0;;7542:2:1;128859:80:0;;;7524:21:1;7581:2;7561:18;;;7554:30;7620:20;7600:18;;;7593:48;7658:18;;128859:80:0;;;;;;;;;69209:1;129034:28;;;:21;;;:28;;;;;;:62;129013:128;;;;-1:-1:-1;;;129013:128:0;;7889:2:1;129013:128:0;;;7871:21:1;7928:2;7908:18;;;7901:30;7967:21;7947:18;;;7940:49;8006:18;;129013:128:0;7687:343:1;129013:128:0;129209:23;129235:43;129256:5;129263:6;129235:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;129271:6:0;;-1:-1:-1;129235:20:0;;-1:-1:-1;129235:43:0:i;:::-;129370:34;;;;:17;;;:34;;;;;;129209:69;;-1:-1:-1;129370:39:0;129366:143;;70782:35;;;;:21;;;;;:35;;;;;;:45;-1:-1:-1;129494:4:0;129487:11;;129366:143;129525:5;129518:12;;;;;128509:1028;;;;;;;:::o;126187:158::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;8237:2:1;111848:68:0;;;8219:21:1;;;8256:18;;;8249:30;8315:34;8295:18;;;8288:62;8367:18;;111848:68:0;8035:356:1;66801:107:0;66858:7;66884:17;:6;66894;66884:9;:17::i;:::-;66877:24;66801:107;-1:-1:-1;;66801:107:0:o;123772:271::-;123952:46;123958:13;123973:8;123983:6;123991;123952:5;:46::i;:::-;123944:65;;;;-1:-1:-1;;;123944:65:0;;8598:2:1;123944:65:0;;;8580:21:1;8637:1;8617:18;;;8610:29;8675:8;8655:18;;;8648:36;8701:18;;123944:65:0;8396:329:1;123944:65:0;124019:17;124027:8;124019:7;:17::i;:::-;123772:271;;;;:::o;117488:57::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;8237:2:1;111848:68:0;;;8219:21:1;;;8256:18;;;8249:30;8315:34;8295:18;;;8288:62;8367:18;;111848:68:0;8035:356:1;111848:68:0;117488:57::o;121084:295::-;106824:19;106846:25;106869:1;106846:22;:25::i;:::-;106824:47;;106885:14;106881:65;;;106915:13;:20;;;;;;;;106881:65;121173:29:::1;:27;:29::i;:::-;121212:35;121223:13;121238:8;121212:10;:35::i;:::-;-1:-1:-1::0;121290:7:0::1;:11:::0;;;::::1;121300:1;121290:11;::::0;;121343:29:::1;121358:13:::0;129826:12;;129841:1;129826:16;129660:20;129862:25;;;:11;:25;;;;;70254:36;;;;;;;70300:37;;;;;;;;;;;129925:12;:27;;;129940:12;129596:363;-1:-1:-1;129596:363:0;121343:29:::1;121311;::::0;::::1;;::::0;;;:14:::1;:29;::::0;;;;:61;106966:99;;;;107016:5;107000:21;;;;;;107040:14;;-1:-1:-1;6782:36:1;;107040:14:0;;6770:2:1;6755:18;107040:14:0;;;;;;;106814:257;121084:295;;:::o;124481:1415::-;124538:10;124551:22;:8;:20;:22::i;:::-;124538:35;-1:-1:-1;124583:15:0;124601:11;-1:-1:-1;;124601:9:0;;;:11::i;:::-;124583:29;-1:-1:-1;124622:20:0;124645:16;-1:-1:-1;;124645:14:0;;;:16::i;:::-;124720:29;;;;124671:34;124720:29;;;:14;:29;;;;;;;;;124708:42;;:11;:42;;;;;124622:39;;-1:-1:-1;124845:11:0;124820:36;:21;-1:-1:-1;;124820:19:0;;;:21::i;:::-;:36;;;124812:61;;;;-1:-1:-1;;;124812:61:0;;9131:2:1;124812:61:0;;;9113:21:1;9170:2;9150:18;;;9143:30;9209:14;9189:18;;;9182:42;9241:18;;124812:61:0;8929:336:1;124812:61:0;124925:20;124948:11;-1:-1:-1;;124948:9:0;;;:11::i;:::-;124969:13;124985:35;;;:21;;;:35;;;;;;124925:34;;-1:-1:-1;125038:33:0;124985:35;125038:26;:33::i;:::-;125030:66;;;;-1:-1:-1;;;125030:66:0;;9472:2:1;125030:66:0;;;9454:21:1;9511:2;9491:18;;;9484:30;9550:22;9530:18;;;9523:50;9590:18;;125030:66:0;9270:344:1;125030:66:0;125127:65;125142:13;125157:27;-1:-1:-1;;125157:25:0;;;:27::i;:::-;125186:5;125127:14;:65::i;:::-;125106:130;;;;-1:-1:-1;;;125106:130:0;;9821:2:1;125106:130:0;;;9803:21:1;9860:2;9840:18;;;9833:30;9899:20;9879:18;;;9872:48;9937:18;;125106:130:0;9619:342:1;125106:130:0;125289:7;;;;;:12;125281:35;;;;-1:-1:-1;;;125281:35:0;;10168:2:1;125281:35:0;;;10150:21:1;10207:2;10187:18;;;10180:30;10246:12;10226:18;;;10219:40;10276:18;;125281:35:0;9966:334:1;125281:35:0;125326:7;:11;;;;;;125347:21;125358:9;-1:-1:-1;;125358:7:0;;;:9::i;:::-;125347:10;:21::i;:::-;70782:35;;;;:21;;;:35;;;;;69284:1;70782:45;;125529:43;125552:19;-1:-1:-1;;125552:17:0;;;:19::i;:::-;125529:22;:43::i;:::-;125509:63;-1:-1:-1;125582:35:0;;;;125631:13;125658:15;-1:-1:-1;;125658:13:0;;;:15::i;:::-;125687:16;-1:-1:-1;;125687:14:0;;;:16::i;:::-;125717:24;;;;:17;;;:24;;;;;;125755:17;:9;-1:-1:-1;;125755:7:0;;;:9::i;:::-;-1:-1:-1;;125755:15:0;;:17::i;:::-;125582:200;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;125797:36:0;;125820:12;;-1:-1:-1;125797:36:0;;;;-1:-1:-1;125797:36:0;;;;;-1:-1:-1;;125878:7:0;:11;;;;125888:1;125878:11;;;-1:-1:-1;;;;;;124481:1415:0:o;126696:423::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;8237:2:1;111848:68:0;;;8219:21:1;;;8256:18;;;8249:30;8315:34;8295:18;;;8288:62;8367:18;;111848:68:0;8035:356:1;111848:68:0;126886:29:::1;::::0;;::::1;126837:34;126886:29:::0;;;:14:::1;:29;::::0;;;;;;;;126874:42;;:11:::1;:42:::0;;;;;126955:24;;;:17:::1;::::0;::::1;:24:::0;;;;;;;126874:42;;126989:39:::1;::::0;126874:42;;126973:5;;127017:10;;126989:20:::1;:39;:::i;:::-;127043:69;::::0;;11566:25:1;;;11622:2;11607:18;;11600:34;;;127074:5:0;;127043:69:::1;::::0;::::1;::::0;::::1;::::0;11539:18:1;127043:69:0::1;;;;;;;126827:292;;126696:423:::0;;;:::o;66694:101::-;66738:16;66773:15;:6;:13;:15::i;117162:133::-;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;8237:2:1;111848:68:0;;;8219:21:1;;;8256:18;;;8249:30;8315:34;8295:18;;;8288:62;8367:18;;111848:68:0;8035:356:1;111848:68:0;117254:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;117162:133::o;131927:225::-;132075:29;;;;132063:42;132075:29;;;:14;:29;;;;;;;;;132063:42;;:11;:42;;;;;:82;;132123:12;;132137:7;;132063:59;:82;:::i;131668:129::-;52449:24;;;131740:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;;131763:27;52342:152;112526:198;111716:6;;111856:23;111716:6;110644:10;111856:23;111848:68;;;;-1:-1:-1;;;111848:68:0;;8237:2:1;111848:68:0;;;8219:21:1;;;8256:18;;;8249:30;8315:34;8295:18;;;8288:62;8367:18;;111848:68:0;8035:356:1;111848:68:0;112614:22:::1;::::0;::::1;112606:73;;;::::0;-1:-1:-1;;;112606:73:0;;11847:2:1;112606:73:0::1;::::0;::::1;11829:21:1::0;11886:2;11866:18;;;11859:30;11925:34;11905:18;;;11898:62;11996:8;11976:18;;;11969:36;12022:19;;112606:73:0::1;11645:402:1::0;112606:73:0::1;112689:28;112708:8;112689:18;:28::i;:::-;112526:198:::0;:::o;122539:801::-;122615:13;122632:30;122649:12;122632:16;:30::i;:::-;122612:50;;;122672:19;122694:25;:5;:23;;;;:25::i;:::-;122672:47;;122753:11;122737:27;;:12;:27;;;122729:68;;;;-1:-1:-1;;;122729:68:0;;12254:2:1;122729:68:0;;;12236:21:1;12293:2;12273:18;;;12266:30;12332;12312:18;;;12305:58;12380:18;;122729:68:0;12052:352:1;122729:68:0;122807:12;122822:24;-1:-1:-1;;122822:22:0;;;:24::i;:::-;122905:28;;;;122856:34;122905:28;;;:14;:28;;;;;;;;;122893:41;;:11;:41;;;;;122960:13;;122807:39;;-1:-1:-1;122893:41:0;122960:13;;122952:21;;;;122944:65;;;;-1:-1:-1;;;122944:65:0;;12611:2:1;122944:65:0;;;12593:21:1;12650:2;12630:18;;;12623:30;12689:33;12669:18;;;12662:61;12740:18;;122944:65:0;12409:355:1;122944:65:0;123019:15;123037:23;-1:-1:-1;;123037:21:0;;;:23::i;:::-;70593:24;;;;:17;;;:24;;;;;123100:15;70593:37;;123019:41;-1:-1:-1;70427:22:0;;;;;;;;;;123266:7;123247:5;123188:145;;123221:12;123188:145;;;123287:36;:28;:5;:26;;;;:28::i;:36::-;123188:145;;;;;;:::i;:::-;;;;;;;;122602:738;;;;;122539:801;:::o;60447:115::-;60510:7;60536:19;60544:3;56062:18;;55980:107;50841:327;52449:24;;;50912:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;50928:45;;-1:-1:-1;50968:5:0;50961:12;;50928:45;50983:23;;;;;;;:14;:23;;;;;;;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;51066:23;;;:30;;51030:15;:24;;;;;:33;;;;;;;;;:66;;;;51111:29;3284:74:1;;;51111:29:0;;3257:18:1;51111:29:0;;;;;;;-1:-1:-1;51157:4:0;50841:327;;;;:::o;118130:132::-;118218:15;;;;118196:10;:38;118188:67;;;;-1:-1:-1;;;118188:67:0;;13193:2:1;118188:67:0;;;13175:21:1;13232:2;13212:18;;;13205:30;13271:18;13251;;;13244:46;13307:18;;118188:67:0;12991:340:1;74819:614:0;74998:5;74959:16;75014:413;71212:2;75034:1;:14;75014:413;;;75100:4;75085:11;;;75084:20;75066:15;75134:7;75095:1;75134:10;;;;;;;:::i;:::-;;;;;75118:26;;75162:7;75173:1;75162:12;75158:200;;75215:33;;;;;;13682:19:1;;;13717:12;;;13710:28;;;13754:12;;75215:33:0;;;;;;;;;;;;75205:44;;;;;;75194:55;;75158:200;;;75309:33;;;;;;13682:19:1;;;13717:12;;;13710:28;;;13754:12;;75309:33:0;;;;;;;;;;;;75299:44;;;;;;75288:55;;75158:200;-1:-1:-1;;75399:3:0;;75014:413;;;;74819:614;;;;;:::o;70643:191::-;70782:35;;;;:21;;;;:35;;;;;:45;70643:191::o;60904:156::-;60978:7;61028:22;61032:3;61044:5;61028:3;:22::i;109000:808::-;109064:4;109397:13;;;;;;;109393:409;;;109451:7;:12;;109462:1;109451:12;:61;;;;-1:-1:-1;109506:4:0;97971:19;:23;109451:61;109426:166;;;;-1:-1:-1;;;109426:166:0;;13979:2:1;109426:166:0;;;13961:21:1;14018:2;13998:18;;;13991:30;14057:34;14037:18;;;14030:62;14128:16;14108:18;;;14101:44;14162:19;;109426:166:0;13777:410:1;109426:166:0;-1:-1:-1;109613:5:0;;109000:808;-1:-1:-1;109000:808:0:o;109393:409::-;109657:12;;:22;;;;:12;;:22;109649:81;;;;-1:-1:-1;;;109649:81:0;;13979:2:1;109649:81:0;;;13961:21:1;14018:2;13998:18;;;13991:30;14057:34;14037:18;;;14030:62;14128:16;14108:18;;;14101:44;14162:19;;109649:81:0;13777:410:1;109649:81:0;-1:-1:-1;109744:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;109000:808:0:o;109393:409::-;109000:808;;;:::o;115751:108::-;108411:13;;;;;;;108403:69;;;;-1:-1:-1;;;108403:69:0;;14394:2:1;108403:69:0;;;14376:21:1;14433:2;14413:18;;;14406:30;14472:34;14452:18;;;14445:62;14543:13;14523:18;;;14516:41;14574:19;;108403:69:0;14192:407:1;108403:69:0;115826:26:::1;:24;:26::i;83280:126::-:0;83347:7;83373:26;:8;80868:4;83373:12;:26::i;83530:305::-;83609:7;83590:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;83647:181:::1;83673:8;83699:35;83711:8;83721:12;83699:11;:35::i;:::-;83752:33;83764:8;83774:10;83752:11;:33::i;:::-;80924:12;83647:8;:181::i;:::-;83628:200;;81152:1;83530:305:::0;;;;:::o;87132:151::-;87208:6;87190:7;86212:37;80924:12;80917:20;-1:-1:-1;;86212:16:0;;;;:37::i;:::-;-1:-1:-1;87240:35:0::1;-1:-1:-1::0;;87240:17:0;::::1;85891:1;87273;87240:17;:35::i;87733:161::-:0;87814:6;87796:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87846:40:0::1;-1:-1:-1::0;;87846:17:0;::::1;86043:2;87884:1;87846:17;:40::i;22455:290::-:0;22511:14;22537:12;22552;22556:7;15386:3;15382:17;2670:26;15378:29;;15059:364;22552:12;22537:27;;;;22574:12;22589;22593:7;16492:2;16488:16;2670:26;16484:28;;16246:282;22589:12;22574:27;;22708:21;;;;22455:290;-1:-1:-1;;;22455:290:0:o;70963:182::-;71034:4;71057:36;;;;;:81;;-1:-1:-1;;69284:1:0;71097:41;;;70963:182::o;88171:174::-;88258:6;88240:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;88290:47:0::1;-1:-1:-1::0;;88290:17:0;::::1;86158:2;88335:1;88290:17;:47::i;83957:299::-:0;84034:7;84015:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;84072:177:::1;84098:8;84124:33;84136:8;84146:10;84124:11;:33::i;:::-;84175;84187:8;84197:10;84175:11;:33::i;:::-;80987:10;83647:8;:181::i;132158:221::-:0;132226:146;132247:18;-1:-1:-1;;132247:16:0;;;:18::i;:::-;132279;-1:-1:-1;;132279:16:0;;;:18::i;:::-;132311:17;-1:-1:-1;;132311:15:0;;;:17::i;:::-;132342:20;-1:-1:-1;;132342:18:0;;;:20::i;:::-;132226:146;;;14837:26:1;14890:15;;;14872:34;;14942:15;;;14937:2;14922:18;;14915:43;14994:15;;;14974:18;;;14967:43;15046:15;;;15041:2;15026:18;;15019:43;132226:146:0;;;;;;14814:3:1;132226:146:0;;;132158:221;:::o;87960:147::-;88039:7;88021;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;88065:35:0::1;-1:-1:-1::0;;88065:13:0;::::1;86096:2;88097;88065:13;:35::i;130458:643::-:0;130533:17;130635:41;;;130631:464;;-1:-1:-1;;130938:15:0;;;;;109000:808::o;130631:464::-;131073:10;131046:38;80154:127;87527:149;87602:6;87584:7;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87634:34:0::1;-1:-1:-1::0;;87634:17:0;::::1;85988:2;87666:1;87634:17;:34::i;87335:141::-:0;87411:7;87393;86212:37;80924:12;80917:20;;86212:37;-1:-1:-1;87437:32:0::1;-1:-1:-1::0;;87437:13:0;::::1;85940:1;87466:2;87437:13;:32::i;84378:190::-:0;84455:7;84436:8;81112:30;-1:-1:-1;;81112:16:0;;80868:4;81112:16;:30::i;:::-;;84481:80:::1;84490:8;84500:33;84512:8;84522:10;84500:11;:33::i;:::-;16492:2:::0;16488:16;;;2670:26;16484:28;81048:10:::1;83647:8;:181::i;28308:632::-:0;28363:16;28391:11;28412:12;28427;28431:7;16492:2;16488:16;2670:26;16484:28;;16246:282;28427:12;28412:27;;;;28549:4;28543:11;28536:18;;28604:3;28597:10;;28650:33;28663:7;28672:3;28678:4;28672:10;28650:12;:33::i;:::-;-1:-1:-1;28807:14:0;;;28823:4;28803:25;28797:4;28790:39;28870:17;;28308:632;;-1:-1:-1;28308:632:0:o;70462:175::-;70593:24;;;;:17;;;;:24;;;;;:37;70462:175::o;61600:257::-;61663:16;61691:22;61716:19;61724:3;61716:7;:19::i;112878:187::-;112970:6;;;;112986:17;;;;;;;;;;;113018:40;;112970:6;;;112986:17;112970:6;;113018:40;;112951:16;;113018:40;112941:124;112878:187;:::o;47552:470::-;47652:16;;47707:19;:12;47652:16;47707;:19::i;:::-;47699:27;-1:-1:-1;32963:2:0;2670:26;16492:2;16488:16;;;16484:28;34217:37;47736:52;;;;-1:-1:-1;;;47736:52:0;;15275:2:1;47736:52:0;;;15257:21:1;15314:2;15294:18;;;15287:30;15353:20;15333:18;;;15326:48;15391:18;;47736:52:0;15073:342:1;47736:52:0;47809:115;47841:23;-1:-1:-1;;47841:21:0;;;:23::i;:::-;47878:36;:28;-1:-1:-1;;47878:26:0;;;:28::i;:36::-;47809:18;:115::i;:::-;47798:126;-1:-1:-1;47942:46:0;47952:25;-1:-1:-1;;47952:23:0;;;:25::i;:::-;52449:24;;52426:4;52449:24;;;:15;:24;;;;;;;;:33;;;;;;;;;;;:38;;;52342:152;47942:46;47934:81;;;;-1:-1:-1;;;47934:81:0;;15622:2:1;47934:81:0;;;15604:21:1;15661:2;15641:18;;;15634:30;15700:24;15680:18;;;15673:52;15742:18;;47934:81:0;15420:346:1;47934:81:0;47552:470;;;:::o;34358:143::-;34423:6;34455:38;-1:-1:-1;;34455:15:0;;34423:6;34491:1;34455:15;:38::i;34615:136::-;34679:6;34711:32;-1:-1:-1;;34711:15:0;;32857:1;;34711:15;:32::i;34844:124::-;34907:7;34933:28;-1:-1:-1;;34933:11:0;;32904:1;34958:2;34933:11;:28::i;35312:172::-;35380:7;35406:71;32963:2;35436:37;32963:2;16492;16488:16;;;2670:26;16484:28;35436:37;:::i;:::-;-1:-1:-1;;35406:11:0;;;:71;35475:1;35406:11;:71::i;56429:118::-;56496:7;56522:3;:11;;56534:5;56522:18;;;;;;;;:::i;:::-;;;;;;;;;56515:25;;56429:118;;;;:::o;111457:111::-;108411:13;;;;;;;108403:69;;;;-1:-1:-1;;;108403:69:0;;14394:2:1;108403:69:0;;;14376:21:1;14433:2;14413:18;;;14406:30;14472:34;14452:18;;;14445:62;14543:13;14523:18;;;14516:41;14574:19;;108403:69:0;14192:407:1;108403:69:0;111529:32:::1;110644:10:::0;111529:18:::1;:32::i;13655:359::-:0;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;:::-;13974:33;13655:359;-1:-1:-1;;;;;13655:359:0:o;10073:578::-;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;16268:31:1;10385:186:0;;;16256:44:1;16319:66;16423:3;16419:16;;;16415:25;;16401:12;;;16394:47;16471:15;16457:12;;;16450:37;16521:16;;;16517:25;16503:12;;;16496:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;16559:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;-1:-1:-1;;;10599:11:0;;;;;;;;:::i;10170:451::-;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;85090:164::-;85164:7;85190:57;81794:1;85217:5;85209:14;;;;;;;;:::i;:::-;:26;;;;:::i;:::-;-1:-1:-1;;85190:18:0;;;81794:1;85190:18;:57::i;84805:218::-;84946:7;84972:44;84987:5;84994:11;84987:5;84994:3;:11;:::i;:::-;-1:-1:-1;;84972:14:0;;;:44;85007:8;84972:14;:44::i;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;90631:149::-;90705:6;90689:5;89277:35;80987:10;80980:18;;89277:35;-1:-1:-1;90737:35:0::1;-1:-1:-1::0;;90737:15:0;::::1;89072:1;90769:2;90737:15;:35::i;:::-;90723:50;;::::0;90631:149;-1:-1:-1;;;90631:149:0:o;90827:::-;90901:6;90885:5;89277:35;80987:10;80980:18;;89277:35;-1:-1:-1;90933:35:0::1;-1:-1:-1::0;;90933:15:0;::::1;89122:2;90965;90933:15;:35::i;91022:147::-:0;91095:6;91079:5;89277:35;80987:10;80980:18;;89277:35;-1:-1:-1;91127:34:0::1;-1:-1:-1::0;;91127:15:0;::::1;89172:2;91158;91127:15;:34::i;91218:153::-:0;91294:6;91278:5;89277:35;80987:10;80980:18;;89277:35;-1:-1:-1;91326:37:0::1;-1:-1:-1::0;;91326:15:0;::::1;89225:2;91360;91326:15;:37::i;20004:771::-:0;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;-1:-1:-1;;;20263:76:0;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;-1:-1:-1;;;20359:83:0;;17684:2:1;20359:83:0;;;17666:21:1;17723:2;17703:18;;;17696:30;17762:34;17742:18;;;17735:62;17833:28;17813:18;;;17806:56;17879:19;;20359:83:0;17482:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;27036:902::-;27114:15;-1:-1:-1;;7972:15:0;;;;27141:69;;;;-1:-1:-1;;;27141:69:0;;18111:2:1;27141:69:0;;;18093:21:1;18150:2;18130:18;;;18123:30;18189:34;18169:18;;;18162:62;18260:10;18240:18;;;18233:38;18288:19;;27141:69:0;17909:404:1;27141:69:0;27228:16;27236:7;27228;:16::i;:::-;27220:72;;;;-1:-1:-1;;;27220:72:0;;18520:2:1;27220:72:0;;;18502:21:1;18559:2;18539:18;;;18532:30;18598:34;18578:18;;;18571:62;18669:13;18649:18;;;18642:41;18700:19;;27220:72:0;18318:407:1;27220:72:0;27302:12;27317;27321:7;16492:2;16488:16;2670:26;16484:28;;16246:282;27317:12;27302:27;;;;27339:15;27357:12;27361:7;15386:3;15382:17;2670:26;15378:29;;15059:364;27357:12;27339:30;;;;27380:11;27501:4;27495:11;27488:18;;27588:7;27583:3;27580:16;27577:94;;;27628:4;27622;27615:18;27577:94;27843:4;27834:7;27828:4;27819:7;27816:1;27809:5;27798:50;27794:55;27879:52;27900:15;27907:7;14417:3;14413:17;;14206:268;27900:15;12061:27;12065:2;12061:27;;;;12135:17;;12127:26;;12199:17;;12195:2;12191:26;;11811:446;27879:52;27869:62;27036:902;-1:-1:-1;;;;;;27036:902:0:o;57087:109::-;57143:16;57178:3;:11;;57171:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57087:109;;;:::o;35074:155::-;35137:7;35163:59;-1:-1:-1;;35163:11:0;;35137:7;32963:2;35137:7;35163:11;:59::i;46716:285::-;46826:14;;46873;-1:-1:-1;;46873:12:0;;;:14::i;:::-;46856:31;;46906:36;46935:6;45309:58;;20487:66:1;45309:58:0;;;20475:79:1;20570:12;;;20563:28;;;45179:7:0;;20607:12:1;;45309:58:0;;;;;;;;;;;;45299:69;;;;;;45292:76;;45110:265;;;;46906:36;46897:45;;46961:33;46975:6;46983:10;46961:13;:33::i;17129:399::-;17268:7;17287:12;17302;17306:7;15386:3;15382:17;2670:26;15378:29;;15059:364;17302:12;17287:27;;;;17398:12;17402:7;17398:3;:12::i;:::-;17391:4;17375:13;17382:6;17375:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17371:77;;;-1:-1:-1;;17426:11:0;;;;;17371:77;17465:13;17472:6;17465:4;:13;:::i;:::-;17458:20;;17495:26;17501:7;17495:26;;17510:4;17516;12796:462;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;-1:-1:-1;;12065:2:0;12061:27;;;12135:17;;;;12127:26;;;12199:17;12195:2;12191:26;;12796:462::o;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19061:33;;;19244:1;19306;19386;19448;19130:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19104:391;;18926:576;;;;18761:741;;;;;;:::o;8645:333::-;8702:8;8726:15;8733:7;14417:3;14413:17;;14206:268;8726:15;:31;;8745:12;8726:31;8722:74;;-1:-1:-1;8780:5:0;;8645:333;-1:-1:-1;8645:333:0:o;8722:74::-;8805:12;8820;8824:7;8820:3;:12::i;:::-;8955:4;8949:11;-1:-1:-1;8936:26:0;;8645:333;-1:-1:-1;;;8645:333:0:o;41406:227::-;41484:7;41504:17;41523:18;41545:27;41556:4;41562:9;41545:10;:27::i;:::-;41503:69;;;;41582:18;41594:5;41582:11;:18::i;16702:147::-;16755:7;16820:12;16824:7;16492:2;16488:16;2670:26;16484:28;;16246:282;16820:12;16805;16809:7;15386:3;15382:17;2670:26;15378:29;;15059:364;16805:12;:27;16798:34;;;;16702:147;;;:::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;39341:1279::-;39422:7;39431:12;39652:9;:16;39672:2;39652:22;39648:966;;39941:4;39926:20;;39920:27;39990:4;39975:20;;39969:27;40047:4;40032:20;;40026:27;39690:9;40018:36;40088:25;40099:4;40018:36;39920:27;39969;40088:10;:25::i;:::-;40081:32;;;;;;;;;39648:966;40134:9;:16;40154:2;40134:22;40130:484;;40403:4;40388:20;;40382:27;40453:4;40438:20;;40432:27;40493:23;40504:4;40382:27;40432;40493:10;:23::i;:::-;40486:30;;;;;;;;40130:484;-1:-1:-1;40563:1:0;;-1:-1:-1;40567:35:0;40130:484;39341:1279;;;;;:::o;37646:631::-;37723:20;37714:5;:29;;;;;;;;:::i;:::-;;37710:561;;37646:631;:::o;37710:561::-;37819:29;37810:5;:38;;;;;;;;:::i;:::-;;37806:465;;37864:34;;-1:-1:-1;;;37864:34:0;;20832:2:1;37864:34:0;;;20814:21:1;20871:2;20851:18;;;20844:30;20910:26;20890:18;;;20883:54;20954:18;;37864:34:0;20630:348:1;37806:465:0;37928:35;37919:5;:44;;;;;;;;:::i;:::-;;37915:356;;37979:41;;-1:-1:-1;;;37979:41:0;;21185:2:1;37979:41:0;;;21167:21:1;21224:2;21204:18;;;21197:30;21263:33;21243:18;;;21236:61;21314:18;;37979:41:0;20983:355:1;37915:356:0;38050:30;38041:5;:39;;;;;;;;:::i;:::-;;38037:234;;38096:44;;-1:-1:-1;;;38096:44:0;;21545:2:1;38096:44:0;;;21527:21:1;21584:2;21564:18;;;21557:30;21623:34;21603:18;;;21596:62;21694:4;21674:18;;;21667:32;21716:19;;38096:44:0;21343:398:1;38037:234:0;38170:30;38161:5;:39;;;;;;;;:::i;:::-;;38157:114;;38216:44;;-1:-1:-1;;;38216:44:0;;21948:2:1;38216:44:0;;;21930:21:1;21987:2;21967:18;;;21960:30;22026:34;22006:18;;;21999:62;22097:4;22077:18;;;22070:32;22119:19;;38216:44:0;21746:398:1;2943:1393:0;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;42814:1603::-;42940:7;;43864:66;43851:79;;43847:161;;;-1:-1:-1;43962:1:0;;-1:-1:-1;43966:30:0;43946:51;;43847:161;44021:1;:7;;44026:2;44021:7;;:18;;;;;44032:1;:7;;44037:2;44032:7;;44021:18;44017:100;;;-1:-1:-1;44071:1:0;;-1:-1:-1;44075:30:0;44055:51;;44017:100;44228:24;;;44211:14;44228:24;;;;;;;;;22376:25:1;;;22449:4;22437:17;;22417:18;;;22410:45;;;;22471:18;;;22464:34;;;22514:18;;;22507:34;;;44228:24:0;;22348:19:1;;44228:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44228:24:0;;;;;;-1:-1:-1;;44266:20:0;;;44262:101;;44318:1;44322:29;44302:50;;;;;;;44262:101;44381:6;-1:-1:-1;44389:20:0;;-1:-1:-1;42814:1603:0;;;;;;;;:::o;41887:336::-;41997:7;;42055:66;42042:80;;41997:7;42148:25;42164:3;42149:18;;;42171:2;42148:25;:::i;:::-;42132:42;;42191:25;42202:4;42208:1;42211;42214;42191:10;:25::i;:::-;42184:32;;;;;;41887:336;;;;;;:::o;196:163:1:-;263:20;;323:10;312:22;;302:33;;292:61;;349:1;346;339:12;364:324;439:6;447;455;508:2;496:9;487:7;483:23;479:32;476:52;;;524:1;521;514:12;476:52;547:28;565:9;547:28;:::i;:::-;537:38;;594:37;627:2;616:9;612:18;594:37;:::i;:::-;584:47;;678:2;667:9;663:18;650:32;640:42;;364:324;;;;;:::o;885:154::-;971:42;964:5;960:54;953:5;950:65;940:93;;1029:1;1026;1019:12;1044:319;1111:6;1119;1172:2;1160:9;1151:7;1147:23;1143:32;1140:52;;;1188:1;1185;1178:12;1140:52;1211:28;1229:9;1211:28;:::i;:::-;1201:38;;1289:2;1278:9;1274:18;1261:32;1302:31;1327:5;1302:31;:::i;:::-;1352:5;1342:15;;;1044:319;;;;;:::o;1368:180::-;1427:6;1480:2;1468:9;1459:7;1455:23;1451:32;1448:52;;;1496:1;1493;1486:12;1448:52;-1:-1:-1;1519:23:1;;1368:180;-1:-1:-1;1368:180:1:o;1553:184::-;1605:77;1602:1;1595:88;1702:4;1699:1;1692:15;1726:4;1723:1;1716:15;1742:777;1784:5;1837:3;1830:4;1822:6;1818:17;1814:27;1804:55;;1855:1;1852;1845:12;1804:55;1891:6;1878:20;1917:18;1954:2;1950;1947:10;1944:36;;;1960:18;;:::i;:::-;2094:2;2088:9;2156:4;2148:13;;1999:66;2144:22;;;2168:2;2140:31;2136:40;2124:53;;;2192:18;;;2212:22;;;2189:46;2186:72;;;2238:18;;:::i;:::-;2278:10;2274:2;2267:22;2313:2;2305:6;2298:18;2359:3;2352:4;2347:2;2339:6;2335:15;2331:26;2328:35;2325:55;;;2376:1;2373;2366:12;2325:55;2440:2;2433:4;2425:6;2421:17;2414:4;2406:6;2402:17;2389:54;2487:1;2480:4;2475:2;2467:6;2463:15;2459:26;2452:37;2507:6;2498:15;;;;;;1742:777;;;;:::o;2524:609::-;2644:6;2652;2660;2668;2721:4;2709:9;2700:7;2696:23;2692:34;2689:54;;;2739:1;2736;2729:12;2689:54;2762:28;2780:9;2762:28;:::i;:::-;2752:38;;2841:2;2830:9;2826:18;2813:32;2868:18;2860:6;2857:30;2854:50;;;2900:1;2897;2890:12;2854:50;2923:49;2964:7;2955:6;2944:9;2940:22;2923:49;:::i;:::-;2913:59;;;3006:4;2995:9;2991:20;3030:7;3026:2;3023:15;3020:35;;;3051:1;3048;3041:12;3020:35;2524:609;;;;-1:-1:-1;;;3089:2:1;3074:18;;;;;3111:16;;;2524:609::o;3369:252::-;3436:6;3444;3497:2;3485:9;3476:7;3472:23;3468:32;3465:52;;;3513:1;3510;3503:12;3465:52;3536:28;3554:9;3536:28;:::i;:::-;3526:38;3611:2;3596:18;;;;3583:32;;-1:-1:-1;;;3369:252:1:o;4005:320::-;4073:6;4126:2;4114:9;4105:7;4101:23;4097:32;4094:52;;;4142:1;4139;4132:12;4094:52;4182:9;4169:23;4215:18;4207:6;4204:30;4201:50;;;4247:1;4244;4237:12;4201:50;4270:49;4311:7;4302:6;4291:9;4287:22;4270:49;:::i;4330:320::-;4406:6;4414;4422;4475:2;4463:9;4454:7;4450:23;4446:32;4443:52;;;4491:1;4488;4481:12;4443:52;4514:28;4532:9;4514:28;:::i;:::-;4504:38;4589:2;4574:18;;4561:32;;-1:-1:-1;4640:2:1;4625:18;;;4612:32;;4330:320;-1:-1:-1;;;4330:320:1:o;4655:681::-;4826:2;4878:21;;;4948:13;;4851:18;;;4970:22;;;4797:4;;4826:2;5049:15;;;;5023:2;5008:18;;;4797:4;5092:218;5106:6;5103:1;5100:13;5092:218;;;5171:13;;5186:42;5167:62;5155:75;;5285:15;;;;5250:12;;;;5128:1;5121:9;5092:218;;;-1:-1:-1;5327:3:1;;4655:681;-1:-1:-1;;;;;;4655:681:1:o;5341:184::-;5399:6;5452:2;5440:9;5431:7;5427:23;5423:32;5420:52;;;5468:1;5465;5458:12;5420:52;5491:28;5509:9;5491:28;:::i;5530:272::-;5614:6;5667:2;5655:9;5646:7;5642:23;5638:32;5635:52;;;5683:1;5680;5673:12;5635:52;5722:9;5709:23;5741:31;5766:5;5741:31;:::i;6829:184::-;6881:77;6878:1;6871:88;6978:4;6975:1;6968:15;7002:4;6999:1;6992:15;7018:128;7058:3;7089:1;7085:6;7082:1;7079:13;7076:39;;;7095:18;;:::i;:::-;-1:-1:-1;7131:9:1;;7018:128::o;7151:184::-;7203:77;7200:1;7193:88;7300:4;7297:1;7290:15;7324:4;7321:1;7314:15;10305:530;10346:3;10384:5;10378:12;10411:6;10406:3;10399:19;10436:1;10446:162;10460:6;10457:1;10454:13;10446:162;;;10522:4;10578:13;;;10574:22;;10568:29;10550:11;;;10546:20;;10539:59;10475:12;10446:162;;;10626:6;10623:1;10620:13;10617:87;;;10692:1;10685:4;10676:6;10671:3;10667:16;10663:27;10656:38;10617:87;-1:-1:-1;10749:2:1;10737:15;10754:66;10733:88;10724:98;;;;10824:4;10720:109;;10305:530;-1:-1:-1;;10305:530:1:o;10840:547::-;11058:4;11087:10;11136:2;11128:6;11124:15;11113:9;11106:34;11188:2;11180:6;11176:15;11171:2;11160:9;11156:18;11149:43;;11228:6;11223:2;11212:9;11208:18;11201:34;11271:6;11266:2;11255:9;11251:18;11244:34;11315:3;11309;11298:9;11294:19;11287:32;11336:45;11376:3;11365:9;11361:19;11353:6;11336:45;:::i;:::-;11328:53;10840:547;-1:-1:-1;;;;;;;10840:547:1:o;12769:217::-;12916:2;12905:9;12898:21;12879:4;12936:44;12976:2;12965:9;12961:18;12953:6;12936:44;:::i;13336:184::-;13388:77;13385:1;13378:88;13485:4;13482:1;13475:15;13509:4;13506:1;13499:15;15771:125;15811:4;15839:1;15836;15833:8;15830:34;;;15844:18;;:::i;:::-;-1:-1:-1;15881:9:1;;15771:125::o;16806:228::-;16846:7;16972:1;16904:66;16900:74;16897:1;16894:81;16889:1;16882:9;16875:17;16871:105;16868:131;;;16979:18;;:::i;:::-;-1:-1:-1;17019:9:1;;16806:228::o;17039:195::-;17077:4;17114;17111:1;17107:12;17146:4;17143:1;17139:12;17171:3;17166;17163:12;17160:38;;;17178:18;;:::i;:::-;17215:13;;;17039:195;-1:-1:-1;;;17039:195:1:o;17239:238::-;17277:7;17317:4;17314:1;17310:12;17349:4;17346:1;17342:12;17409:3;17403:4;17399:14;17394:3;17391:23;17384:3;17377:11;17370:19;17366:49;17363:75;;;17418:18;;:::i;:::-;17458:13;;17239:238;-1:-1:-1;;;17239:238:1:o;18849:1391::-;19571:34;19559:47;;19636:23;19631:2;19622:12;;19615:45;19679:66;19783:3;19779:16;;;19775:25;;19770:2;19761:12;;19754:47;19820:17;19862:2;19853:12;;19846:24;;;19904:16;;;19900:25;;19895:2;19886:12;;19879:47;19956:34;19951:2;19942:12;;19935:56;20022:3;20016;20007:13;;20000:26;20061:16;;;20057:25;;20051:3;20042:13;;20035:48;20108:3;20099:13;;20092:25;20152:16;;;20148:25;20142:3;20133:13;;20126:48;18807:3;20229;20220:13;;18795:16;-1:-1:-1;18827:11:1;;;20190:44;18730:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"AttestationAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint96","name":"updaterTip","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"relayerTip","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"proverTip","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"processorTip","type":"uint96"}],"name":"LogTips","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"NotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"}],"name":"Process","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"remoteDomain","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"previousConfirmAt","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newConfirmAt","type":"uint256"}],"name":"SetConfirmation","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"acceptableRoot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"activeReplicaConfirmedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_messageId","type":"bytes32"}],"name":"activeReplicaMessageStatus","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"}],"name":"activeReplicaNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_notary","type":"address"}],"name":"addNotary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_notary","type":"address"}],"name":"isNotary","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"process","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"prove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes32[32]","name":"_proof","type":"bytes32[32]"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"proveAndProcess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sensitiveValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"uint256","name":"_confirmAt","type":"uint256"}],"name":"setConfirmation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_remoteDomain","type":"uint32"},{"internalType":"bytes32","name":"_messageHash","type":"bytes32"},{"internalType":"bytes32","name":"_status","type":"bytes32"}],"name":"setMessageStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newValue","type":"uint256"}],"name":"setSensitiveValue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"submitAttestation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"events":{"Process(uint32,bytes32)":{"notice":"Emitted when message is processed"},"SetConfirmation(uint32,bytes32,uint256,uint256)":{"notice":"Emitted when a root's confirmation is modified by governance"}},"kind":"user","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"notice":"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed"},"initialize(uint32,address)":{"notice":"Initialize the replica"},"process(bytes)":{"notice":"Given formatted message, attempts to dispatch message payload to end recipient."},"prove(uint32,bytes,bytes32[32],uint256)":{"notice":"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf."},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"notice":"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message."},"setConfirmation(uint32,bytes32,uint256)":{"notice":"Set confirmAt for a given root"},"setUpdater(uint32,address)":{"notice":"Set Updater role"},"submitAttestation(bytes)":{"notice":"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event."}},"version":1},"developerDoc":{"kind":"dev","methods":{"acceptableRoot(uint32,uint32,bytes32)":{"params":{"_root":"the Merkle root, submitted in an update, to check"},"returns":{"_0":"TRUE iff root has been submitted \u0026 timeout has expired"}},"initialize(uint32,address)":{"details":"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer","params":{"_remoteDomain":"The domain of the Home contract this follows","_updater":"The EVM id of the updater"}},"owner()":{"details":"Returns the address of the current owner."},"process(bytes)":{"details":"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.","params":{"_message":"Formatted message"}},"prove(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message","_proof":"Merkle proof of inclusion for leaf"},"returns":{"_0":"Returns true if proof was valid and `prove` call succeeded*"}},"proveAndProcess(uint32,bytes,bytes32[32],uint256)":{"details":"Reverts if `prove` call returns false","params":{"_index":"Index of leaf in home's merkle tree","_message":"Formatted message (refer to Message library)","_proof":"Merkle proof of inclusion for message's leaf"}},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setConfirmation(uint32,bytes32,uint256)":{"details":"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)","params":{"_confirmAt":"The new confirmation time. Set to 0 to \"delete\" a root.","_root":"The root for which to modify confirm time"}},"setUpdater(uint32,address)":{"details":"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)","params":{"_updater":"New Updater"}},"submitAttestation(bytes)":{"details":"Reverts if update doesn't build off latest committedRoot or if signature is invalid.","params":{"_attestation":"Attestation data and signature"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"AttestationAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"updaterTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"relayerTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"proverTip\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"processorTip\",\"type\":\"uint96\"}],\"name\":\"LogTips\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"domain\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"NotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"}],\"name\":\"Process\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"remoteDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousConfirmAt\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newConfirmAt\",\"type\":\"uint256\"}],\"name\":\"SetConfirmation\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"acceptableRoot\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaConfirmedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageId\",\"type\":\"bytes32\"}],\"name\":\"activeReplicaMessageStatus\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"}],\"name\":\"activeReplicaNonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"addNotary\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_notary\",\"type\":\"address\"}],\"name\":\"isNotary\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"}],\"name\":\"process\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"prove\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[32]\",\"name\":\"_proof\",\"type\":\"bytes32[32]\"},{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"proveAndProcess\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sensitiveValue\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"_confirmAt\",\"type\":\"uint256\"}],\"name\":\"setConfirmation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_remoteDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_messageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"_status\",\"type\":\"bytes32\"}],\"name\":\"setMessageStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newValue\",\"type\":\"uint256\"}],\"name\":\"setSensitiveValue\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_domain\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"submitAttestation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"params\":{\"_root\":\"the Merkle root, submitted in an update, to check\"},\"returns\":{\"_0\":\"TRUE iff root has been submitted \u0026 timeout has expired\"}},\"initialize(uint32,address)\":{\"details\":\"Performs the following action: - initializes inherited contracts - initializes re-entrancy guard - sets remote domain - sets a trusted root, and pre-approves messages under it - sets the optimistic timer\",\"params\":{\"_remoteDomain\":\"The domain of the Home contract this follows\",\"_updater\":\"The EVM id of the updater\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"process(bytes)\":{\"details\":\"Recipient must implement a `handle` method (refer to IMessageRecipient.sol) Reverts if formatted message's destination domain is not the Replica's domain, if message has not been proven, or if recipient reverted upon receiving the message.\",\"params\":{\"_message\":\"Formatted message\"}},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if message's MessageStatus != None (i.e. if message was already proven or processed)For convenience, we allow proving against any previous root. This means that witnesses never need to be updated for the new root\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message\",\"_proof\":\"Merkle proof of inclusion for leaf\"},\"returns\":{\"_0\":\"Returns true if proof was valid and `prove` call succeeded*\"}},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"details\":\"Reverts if `prove` call returns false\",\"params\":{\"_index\":\"Index of leaf in home's merkle tree\",\"_message\":\"Formatted message (refer to Message library)\",\"_proof\":\"Merkle proof of inclusion for message's leaf\"}},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"details\":\"To be used if in the case that fraud is proven and roots need to be deleted / added. Only callable by owner (Governance)\",\"params\":{\"_confirmAt\":\"The new confirmation time. Set to 0 to \\\"delete\\\" a root.\",\"_root\":\"The root for which to modify confirm time\"}},\"setUpdater(uint32,address)\":{\"details\":\"MUST ensure that all roots signed by previous Updater have been relayed before calling. Only callable by owner (Governance)\",\"params\":{\"_updater\":\"New Updater\"}},\"submitAttestation(bytes)\":{\"details\":\"Reverts if update doesn't build off latest committedRoot or if signature is invalid.\",\"params\":{\"_attestation\":\"Attestation data and signature\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"Process(uint32,bytes32)\":{\"notice\":\"Emitted when message is processed\"},\"SetConfirmation(uint32,bytes32,uint256,uint256)\":{\"notice\":\"Emitted when a root's confirmation is modified by governance\"}},\"kind\":\"user\",\"methods\":{\"acceptableRoot(uint32,uint32,bytes32)\":{\"notice\":\"Check that the root has been submitted and that the optimistic timeout period has expired, meaning the root can be processed\"},\"initialize(uint32,address)\":{\"notice\":\"Initialize the replica\"},\"process(bytes)\":{\"notice\":\"Given formatted message, attempts to dispatch message payload to end recipient.\"},\"prove(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"Attempts to prove the validity of message given its leaf, the merkle proof of inclusion for the leaf, and the index of the leaf.\"},\"proveAndProcess(uint32,bytes,bytes32[32],uint256)\":{\"notice\":\"First attempts to prove the validity of provided formatted `message`. If the message is successfully proven, then tries to process message.\"},\"setConfirmation(uint32,bytes32,uint256)\":{\"notice\":\"Set confirmAt for a given root\"},\"setUpdater(uint32,address)\":{\"notice\":\"Set Updater role\"},\"submitAttestation(bytes)\":{\"notice\":\"Called by external agent. Submits the signed attestation, marks root's allowable confirmation time, and emits an `Update` event.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"ReplicaManagerHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74","acceptableRoot(uint32,uint32,bytes32)":"15a046aa","activeReplicaConfirmedAt(uint32,bytes32)":"7dfdba28","activeReplicaMessageStatus(uint32,bytes32)":"63415514","activeReplicaNonce(uint32)":"b65672d3","addNotary(uint32,address)":"2af678b0","allGuards()":"9fe03fa2","getGuard(uint256)":"629ddf69","guardsAmount()":"246c2449","initialize(uint32,address)":"8624c35c","isNotary(uint32,address)":"e98fae1f","localDomain()":"8d3638f4","owner()":"8da5cb5b","process(bytes)":"928bc4b2","prove(uint32,bytes,bytes32[32],uint256)":"4f63be3f","proveAndProcess(uint32,bytes,bytes32[32],uint256)":"68705275","renounceOwnership()":"715018a6","sensitiveValue()":"089d2894","setConfirmation(uint32,bytes32,uint256)":"9df7d36d","setMessageStatus(uint32,bytes32,bytes32)":"bfd84d36","setSensitiveValue(uint256)":"48639d24","setSystemMessenger(address)":"b7bc563e","setUpdater(uint32,address)":"61bc3111","submitAttestation(bytes)":"f646a512","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManagerHarness.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122028d30e262de413764f9374c0c5050a8b900adbe653e2b67fb50650448394b15c64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122028d30e262de413764f9374c0c5050a8b900adbe653e2b67fb50650448394b15c64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"35580:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;35580:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"35580:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:SystemContract":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"SystemContract\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b"}},"solidity/ReplicaManagerHarness.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220822290f2e93bd6009ca8d8a7cb4a4f5a771aa48a155e5faddacc79fb2ee05ba864736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220822290f2e93bd6009ca8d8a7cb4a4f5a771aa48a155e5faddacc79fb2ee05ba864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"91564:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;91564:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"91564:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220043b252cc500c302598c55278e0c81c985b31df4b734c03e0d334d5b30f9e53964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220043b252cc500c302598c55278e0c81c985b31df4b734c03e0d334d5b30f9e53964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"88563:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;88563:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"88563:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122040cbb533e9c4c6d2931030d47b68281ae91292e5e46b5c67e7c22448cfa8a15b64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122040cbb533e9c4c6d2931030d47b68281ae91292e5e46b5c67e7c22448cfa8a15b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"79173:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;79173:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"79173:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{}},"solidity/ReplicaManagerHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220d1b03f95375db81eee8540bd8d7399c4e899bf2267084e590b64a7d348bf1fc164736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220d1b03f95375db81eee8540bd8d7399c4e899bf2267084e590b64a7d348bf1fc164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/ReplicaManagerHarness.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212203f903fa32b0f92d9ee170255579912ffb29b34f63cfdb4688f7e0005d29be1a464736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212203f903fa32b0f92d9ee170255579912ffb29b34f63cfdb4688f7e0005d29be1a464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\ncontract GlobalNotaryRegistry is AbstractNotaryRegistry {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // [domain =\u003e [notaries]]\n mapping(uint32 =\u003e address[]) internal domainNotaries;\n\n // [domain =\u003e [notary =\u003e position in the above array plus 1]]\n // (index 0 means notary is not in the array)\n mapping(uint32 =\u003e mapping(address =\u003e uint256)) private notariesIndexes;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[48] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event NotaryAdded(uint32 indexed domain, address notary);\n\n event NotaryRemoved(uint32 indexed domain, address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(uint32 _domain, address _notary) internal returns (bool) {\n if (_isNotary(_domain, _notary)) return false;\n domainNotaries[_domain].push(_notary);\n notariesIndexes[_domain][_notary] = domainNotaries[_domain].length;\n emit NotaryAdded(_domain, _notary);\n return true;\n }\n\n function _removeNotary(uint32 _domain, address _notary) internal returns (bool) {\n uint256 valueIndex = notariesIndexes[_domain][_notary];\n if (valueIndex == 0) return false;\n // To delete a Notary from the array in O(1),\n // we swap the Notary to delete with the last one in the array,\n // and then remove the last Notary (sometimes called as 'swap and pop').\n address[] storage notaries = domainNotaries[_domain];\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = notaries.length - 1;\n if (lastIndex != toDeleteIndex) {\n address lastNotary = notaries[lastIndex];\n // Move the last Notary to the index where the Notary to delete is\n notaries[toDeleteIndex] = lastNotary;\n // Update the index for the moved Notary\n notariesIndexes[_domain][lastNotary] = valueIndex;\n }\n // Delete the slot where the moved Notary was stored\n notaries.pop();\n // Delete the index for the deleted slot\n delete notariesIndexes[_domain][_notary];\n emit NotaryRemoved(_domain, _notary);\n return true;\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n return notariesIndexes[_domain][_notary] != 0;\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary ReplicaLib {\n // ============ Enums ============\n // Status of Message:\n // 0 - None - message has not been proven or processed\n // 1 - Proven - message inclusion proof has been validated\n // 2 - Processed - message has been dispatched to recipient\n enum MessageStatus {\n None,\n Proven,\n Processed\n }\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum ReplicaStatus {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n /// @dev Should not be possible to have 0x0 or 0x1 as valid Merkle root,\n /// so it's safe to use those values as NONE/PROCESSED\n bytes32 public constant MESSAGE_STATUS_NONE = bytes32(0);\n bytes32 public constant MESSAGE_STATUS_PROCESSED = bytes32(uint256(1));\n\n // TODO: optimize read/writes by further packing?\n struct Replica {\n // The latest nonce that has been signed by the Updater for this given Replica\n uint32 nonce; // 32 bits\n // Domain of home chain\n uint32 remoteDomain; // 32 bits\n // Status of Replica based on the Home remote domain\n ReplicaStatus status; // 8 bits\n // Mapping of roots to time at which Relayer submitted on-chain. Latency period begins here.\n // TODO: confirmAt doesn't need to be uint256 necessarily\n mapping(bytes32 =\u003e uint256) confirmAt;\n // Mapping of message leaves to status:\n // - NONE: message not yet submitted\n // - PROCESSED: message was proven and processed\n // bytes32 root: message was proven against `root`, but not yet processed\n mapping(bytes32 =\u003e bytes32) messageStatus;\n }\n\n function setupReplica(Replica storage replica, uint32 _remoteDomain) internal {\n replica.remoteDomain = _remoteDomain;\n replica.status = ReplicaStatus.Active;\n }\n\n function setNonce(Replica storage replica, uint32 _nonce) internal {\n replica.nonce = _nonce;\n }\n\n function setConfirmAt(\n Replica storage replica,\n bytes32 _root,\n uint256 _confirmAt\n ) internal {\n replica.confirmAt[_root] = _confirmAt;\n }\n\n function setMessageStatus(\n Replica storage replica,\n bytes32 _messageHash,\n bytes32 _status\n ) internal {\n replica.messageStatus[_messageHash] = _status;\n }\n\n function setStatus(Replica storage replica, ReplicaStatus _status) internal {\n replica.status = _status;\n }\n\n function isPotentialRoot(bytes32 messageStatus) internal pure returns (bool) {\n return messageStatus != MESSAGE_STATUS_NONE \u0026\u0026 messageStatus != MESSAGE_STATUS_PROCESSED;\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ninterface IMessageRecipient {\n function handle(\n uint32 _origin,\n uint32 _nonce,\n bytes32 _sender,\n uint256 _rootTimestamp,\n bytes memory _message\n ) external;\n}\n\ncontract ReplicaManager is Version0, SystemContract, GlobalNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using ReplicaLib for ReplicaLib.Replica;\n using MerkleLib for MerkleLib.Tree;\n using Message for bytes;\n using TypedMemView for bytes29;\n using Attestation for bytes29;\n using Message for bytes29;\n using Header for bytes29;\n\n // ============ Public Storage ============\n\n // re-entrancy guard\n uint8 private entered;\n\n uint256 internal replicaCount;\n\n // all Replicas: both active and archived\n mapping(uint256 =\u003e ReplicaLib.Replica) internal allReplicas;\n\n // (domain =\u003e replica index): index of the active replica in allReplicas\n mapping(uint32 =\u003e uint256) internal activeReplicas;\n\n //TODO: Handle fail-over replicas and modify activeReplicas\n // (domain =\u003e [replica indexes]): array of indexes of archived replicas in allReplicas\n mapping(uint32 =\u003e uint256[]) internal archivedReplicas;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[45] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when message is processed\n * @param messageHash The keccak256 hash of the message that was processed\n */\n event Process(uint32 indexed remoteDomain, bytes32 indexed messageHash);\n\n /**\n * @notice Emitted when a root's confirmation is modified by governance\n * @param root The root for which confirmAt has been set\n * @param previousConfirmAt The previous value of confirmAt\n * @param newConfirmAt The new value of confirmAt\n */\n event SetConfirmation(\n uint32 indexed remoteDomain,\n bytes32 indexed root,\n uint256 previousConfirmAt,\n uint256 newConfirmAt\n );\n\n event AttestationAccepted(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n // ============ Constructor ============\n\n //solhint-disable-next-line no-empty-blocks\n constructor(uint32 _localDomain) SystemContract(_localDomain) {}\n\n // ============ Initializer ============\n\n /**\n * @notice Initialize the replica\n * @dev Performs the following action:\n * - initializes inherited contracts\n * - initializes re-entrancy guard\n * - sets remote domain\n * - sets a trusted root, and pre-approves messages under it\n * - sets the optimistic timer\n * @param _remoteDomain The domain of the Home contract this follows\n * @param _updater The EVM id of the updater\n */\n function initialize(uint32 _remoteDomain, address _updater) public initializer {\n __SystemContract_initialize();\n _addNotary(_remoteDomain, _updater);\n // set storage variables\n entered = 1;\n activeReplicas[_remoteDomain] = _createReplica(_remoteDomain);\n }\n\n // ============ Active Replica Views ============\n\n function activeReplicaNonce(uint32 _remoteDomain) external view returns (uint32) {\n return allReplicas[activeReplicas[_remoteDomain]].nonce;\n }\n\n function activeReplicaConfirmedAt(uint32 _remoteDomain, bytes32 _root)\n external\n view\n returns (uint256)\n {\n return allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n }\n\n function activeReplicaMessageStatus(uint32 _remoteDomain, bytes32 _messageId)\n external\n view\n returns (bytes32)\n {\n return allReplicas[activeReplicas[_remoteDomain]].messageStatus[_messageId];\n }\n\n // ============ Archived Replica Views ============\n\n // TODO: getters for archived replicas\n\n // ============ External Functions ============\n\n /**\n * @notice Called by external agent. Submits the signed attestation,\n * marks root's allowable confirmation time, and emits an `Update` event.\n * @dev Reverts if update doesn't build off latest committedRoot\n * or if signature is invalid.\n * @param _attestation Attestation data and signature\n */\n function submitAttestation(bytes memory _attestation) external {\n (, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 remoteDomain = _view.attestationDomain();\n require(remoteDomain != localDomain, \"Update refers to local chain\");\n uint32 nonce = _view.attestationNonce();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[remoteDomain]];\n require(nonce \u003e replica.nonce, \"Update older than current state\");\n bytes32 newRoot = _view.attestationRoot();\n replica.setConfirmAt(newRoot, block.timestamp);\n // update nonce\n replica.setNonce(nonce);\n emit AttestationAccepted(\n remoteDomain,\n nonce,\n newRoot,\n _view.attestationSignature().clone()\n );\n }\n\n /**\n * @notice First attempts to prove the validity of provided formatted\n * `message`. If the message is successfully proven, then tries to process\n * message.\n * @dev Reverts if `prove` call returns false\n * @param _message Formatted message (refer to Message library)\n * @param _proof Merkle proof of inclusion for message's leaf\n * @param _index Index of leaf in home's merkle tree\n */\n function proveAndProcess(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) external {\n require(prove(_remoteDomain, _message, _proof, _index), \"!prove\");\n process(_message);\n }\n\n /**\n * @notice Given formatted message, attempts to dispatch\n * message payload to end recipient.\n * @dev Recipient must implement a `handle` method (refer to IMessageRecipient.sol)\n * Reverts if formatted message's destination domain is not the Replica's domain,\n * if message has not been proven,\n * or if recipient reverted upon receiving the message.\n * @param _message Formatted message\n */\n function process(bytes memory _message) public {\n bytes29 _m = _message.messageView();\n bytes29 _header = _m.header();\n uint32 _remoteDomain = _header.origin();\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure message was meant for this domain\n require(_header.destination() == localDomain, \"!destination\");\n // ensure message has been proven\n bytes32 _messageHash = _m.keccak();\n bytes32 _root = replica.messageStatus[_messageHash];\n require(ReplicaLib.isPotentialRoot(_root), \"!exists || processed\");\n require(\n acceptableRoot(_remoteDomain, _header.optimisticSeconds(), _root),\n \"!optimisticSeconds\"\n );\n // check re-entrancy guard\n require(entered == 1, \"!reentrant\");\n entered = 0;\n _storeTips(_m.tips());\n // update message status as processed\n replica.setMessageStatus(_messageHash, ReplicaLib.MESSAGE_STATUS_PROCESSED);\n address recipient = _checkForSystemMessage(_header.recipient());\n IMessageRecipient(recipient).handle(\n _remoteDomain,\n _header.nonce(),\n _header.sender(),\n replica.confirmAt[_root],\n _m.body().clone()\n );\n emit Process(_remoteDomain, _messageHash);\n // reset re-entrancy guard\n entered = 1;\n }\n\n // ============ External Owner Functions ============\n\n /**\n * @notice Set Updater role\n * @dev MUST ensure that all roots signed by previous Updater have\n * been relayed before calling. Only callable by owner (Governance)\n * @param _updater New Updater\n */\n function setUpdater(uint32 _domain, address _updater) external onlyOwner {\n // TODO: proper implementation\n _addNotary(_domain, _updater);\n }\n\n /**\n * @notice Set confirmAt for a given root\n * @dev To be used if in the case that fraud is proven\n * and roots need to be deleted / added. Only callable by owner (Governance)\n * @param _root The root for which to modify confirm time\n * @param _confirmAt The new confirmation time. Set to 0 to \"delete\" a root.\n */\n function setConfirmation(\n uint32 _remoteDomain,\n bytes32 _root,\n uint256 _confirmAt\n ) external onlyOwner {\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n uint256 _previousConfirmAt = replica.confirmAt[_root];\n replica.setConfirmAt(_root, _confirmAt);\n emit SetConfirmation(_remoteDomain, _root, _previousConfirmAt, _confirmAt);\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check that the root has been submitted\n * and that the optimistic timeout period has expired,\n * meaning the root can be processed\n * @param _root the Merkle root, submitted in an update, to check\n * @return TRUE iff root has been submitted \u0026 timeout has expired\n */\n function acceptableRoot(\n uint32 _remoteDomain,\n uint32 _optimisticSeconds,\n bytes32 _root\n ) public view returns (bool) {\n uint256 _time = allReplicas[activeReplicas[_remoteDomain]].confirmAt[_root];\n if (_time == 0) {\n return false;\n }\n return block.timestamp \u003e= _time + _optimisticSeconds;\n }\n\n /**\n * @notice Attempts to prove the validity of message given its leaf, the\n * merkle proof of inclusion for the leaf, and the index of the leaf.\n * @dev Reverts if message's MessageStatus != None (i.e. if message was\n * already proven or processed)\n * @dev For convenience, we allow proving against any previous root.\n * This means that witnesses never need to be updated for the new root\n * @param _message Formatted message\n * @param _proof Merkle proof of inclusion for leaf\n * @param _index Index of leaf in home's merkle tree\n * @return Returns true if proof was valid and `prove` call succeeded\n **/\n function prove(\n uint32 _remoteDomain,\n bytes memory _message,\n bytes32[32] calldata _proof,\n uint256 _index\n ) public returns (bool) {\n bytes32 _leaf = keccak256(_message);\n ReplicaLib.Replica storage replica = allReplicas[activeReplicas[_remoteDomain]];\n // ensure that replica is active\n require(replica.status == ReplicaLib.ReplicaStatus.Active, \"Replica not active\");\n // ensure that message has not been proven or processed\n require(\n replica.messageStatus[_leaf] == ReplicaLib.MESSAGE_STATUS_NONE,\n \"!MessageStatus.None\"\n );\n // calculate the expected root based on the proof\n bytes32 _calculatedRoot = MerkleLib.branchRoot(_leaf, _proof, _index);\n // if the root is valid, save it for later optimistic period checking\n if (replica.confirmAt[_calculatedRoot] != 0) {\n replica.setMessageStatus(_leaf, _calculatedRoot);\n return true;\n }\n return false;\n }\n\n // ============ Internal Functions ============\n\n function _createReplica(uint32 _remoteDomain) internal returns (uint256 replicaIndex) {\n // Start indexing from 1, so default replica (allReplicas[0]) will be forever inactive\n unchecked {\n replicaIndex = replicaCount + 1;\n }\n allReplicas[replicaIndex].setupReplica(_remoteDomain);\n replicaCount = replicaIndex;\n }\n\n function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) {\n // If the _res length is less than 68, then the transaction failed silently (without a revert message)\n if (_returnData.length \u003c 68) return \"Transaction reverted silently\";\n\n assembly {\n // Slice the sighash.\n _returnData := add(_returnData, 0x04)\n }\n return abi.decode(_returnData, (string)); // All that remains is the revert string\n }\n\n function _checkForSystemMessage(bytes32 _recipient) internal view returns (address recipient) {\n // Check if SYSTEM_SENDER was specified as message recipient\n if (_recipient == SystemMessage.SYSTEM_SENDER) {\n /**\n * @dev Route message to SystemMessenger.\n * Note: Only SystemMessenger contract on origin chain\n * can send such a message (enforced in Home.sol).\n */\n recipient = address(systemMessenger);\n } else {\n // Cast bytes32 to address otherwise\n recipient = TypeCasts.bytes32ToAddress(_recipient);\n }\n }\n\n function _storeTips(bytes29 _tips) internal virtual {\n // TODO: implement storing \u0026 claiming logic\n }\n}\n\n// \ncontract ReplicaManagerHarness is ReplicaManager {\n using ReplicaLib for ReplicaLib.Replica;\n\n uint256 public sensitiveValue;\n using Tips for bytes29;\n\n event LogTips(uint96 updaterTip, uint96 relayerTip, uint96 proverTip, uint96 processorTip);\n\n constructor(uint32 _localDomain) ReplicaManager(_localDomain) {}\n\n function addNotary(uint32 _domain, address _notary) public {\n _addNotary(_domain, _notary);\n }\n\n function isNotary(uint32 _domain, address _notary) public view returns (bool) {\n return _isNotary(_domain, _notary);\n }\n\n function setSensitiveValue(uint256 _newValue) external onlySystemMessenger {\n sensitiveValue = _newValue;\n }\n\n function setMessageStatus(\n uint32 _remoteDomain,\n bytes32 _messageHash,\n bytes32 _status\n ) external {\n allReplicas[activeReplicas[_remoteDomain]].setMessageStatus(_messageHash, _status);\n }\n\n function _storeTips(bytes29 _tips) internal override {\n emit LogTips(\n _tips.updaterTip(),\n _tips.relayerTip(),\n _tips.proverTip(),\n _tips.processorTip()\n );\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"68086:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"68086:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68110:33;;68142:1;68110:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;68110:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/ReplicaManagerHarness.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/ReplicaManagerHarness.sol\":{\"keccak256\":\"0xc127cc8b5b1f5b4bf5e35b2e073c9f95bef5edabc9379b298220b0739b47b545\",\"urls\":[\"bzz-raw://9de586983185158eb5b6edbdbe678584cd465083cf6c9a20fb455ec98ff2f833\",\"dweb:/ipfs/QmPAD9CsoFhb6rQ1rcY5TPU4k4H226A19bfweZFQ8xaHtf\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file diff --git a/core/contracts/test/tipsharness/tipsharness.abigen.go b/core/contracts/test/tipsharness/tipsharness.abigen.go index 05f129901a..bc6b7ce2ee 100644 --- a/core/contracts/test/tipsharness/tipsharness.abigen.go +++ b/core/contracts/test/tipsharness/tipsharness.abigen.go @@ -31,7 +31,7 @@ var ( // HeaderMetaData contains all meta data concerning the Header contract. var HeaderMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220167fb68c855f9d771928b270486ee53bdcab38b844708f0dbf70226009ffadd964736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205365420036cda746eb8352956b3072ebeae2af69625c55afcc8e67104df4316464736f6c634300080d0033", } // HeaderABI is the input ABI used to generate the binding from. @@ -204,7 +204,7 @@ func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method str // MessageMetaData contains all meta data concerning the Message contract. var MessageMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206d6e95f83e9c6348bfd4e4725fa30f7e844bf8bf4a80949347662bc32525e74e64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220197ca01069b17f5799ef5da3d241af37ec5800195e5180d76bfa64701a739b3564736f6c634300080d0033", } // MessageABI is the input ABI used to generate the binding from. @@ -377,7 +377,7 @@ func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method s // TipsMetaData contains all meta data concerning the Tips contract. var TipsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220054f1d90244b4e1f649d7b1f810440c4af932c944e591f693a79040e1035dbf364736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220afc6e3c028c4a3ba975d2e5743574dc8ea4e4a296d7c25af1359472490ce8ac564736f6c634300080d0033", } // TipsABI is the input ABI used to generate the binding from. @@ -566,7 +566,7 @@ var TipsHarnessMetaData = &bind.MetaData{ "91864805": "totalTips(bytes29)", "8ff916f8": "updaterTip(bytes29)", }, - Bin: "0x608060405234801561001057600080fd5b50610f46806100206000396000f3fe608060405234801561001057600080fd5b50600436106100e95760003560e01c8063918648051161008c578063c46647e211610066578063c46647e2146101ad578063cc6a5c9b146101c0578063d024f867146101d3578063ec000108146101e657600080fd5b8063918648051461018057806398de855414610193578063aa02b2b21461019a57600080fd5b806360fb5709116100c857806360fb57091461013b5780637137088914610151578063725bd463146101585780638ff916f81461016d57600080fd5b806232b444146100ee57806301fab8df146101045780631c9caa041461010b575b600080fd5b600e5b6040519081526020015b60405180910390f35b60266100f1565b61011e610119366004610c36565b61020e565b6040516bffffffffffffffffffffffff90911681526020016100fb565b60015b60405161ffff90911681526020016100fb565b60026100f1565b61016061021f565b6040516100fb9190610cc7565b61011e61017b366004610c36565b610283565b61011e61018e366004610c36565b61028e565b601a6100f1565b61011e6101a8366004610c36565b610299565b61013e6101bb366004610c36565b6102a4565b61011e6101ce366004610c36565b6102af565b6101606101e1366004610cfb565b6102ba565b6101f96101f4366004610d7e565b61034c565b60405162ffffff1990911681526020016100fb565b600061021982610357565b92915050565b606061027e604080517e010000000000000000000000000000000000000000000000000000000000006020820152600060228201819052602e8201819052603a8201819052604682015281518082036032018152605290910190915290565b905090565b600061021982610390565b6000610219826103b1565b600061021982610408565b600061021982610429565b60006102198261044a565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a087811b8216602284015286811b8216602e84015285811b8216603a84015284901b1660468201528151808203603201815260529091019091526060905b95945050505050565b60006102198261046b565b60008161036d60025b62ffffff19831690610478565b5061038162ffffff1984166026600c61059c565b63ffffffff1691505b50919050565b60008161039d6002610360565b5061038162ffffff1984166002600c61059c565b6000816103be6002610360565b506103c883610357565b6103d18461044a565b6103da85610408565b6103e386610390565b6103ed9190610e7c565b6103f79190610e7c565b6104019190610e7c565b9392505050565b6000816104156002610360565b5061038162ffffff198416600e600c61059c565b6000816104366002610360565b5061040162ffffff1984166000600261059c565b6000816104576002610360565b5061038162ffffff198416601a600c61059c565b60006102198260026105cc565b600061048483836105e7565b6105955760006104a36104978560d81c90565b64ffffffffff1661060a565b91505060006104b88464ffffffffff1661060a565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60405180910390fd5b5090919050565b60006105a9826020610eac565b6105b4906008610ecf565b60ff166105c28585856106f4565b901c949350505050565b81516000906020840161034364ffffffffff851682846108e6565b60008164ffffffffff166105fb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561067d576000610629826008610ecf565b60ff1685901c905061063a8161092d565b61ffff16841793508160ff1660101461065557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610610565b50600f5b60ff8160ff1610156106ee57600061069a826008610ecf565b60ff1685901c90506106ab8161092d565b61ffff16831792508160ff166000146106c657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610681565b50915091565b60008160ff1660000361070957506000610401565b6107218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661073c60ff841685610ef8565b11156107ce5761079b61075d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166107838660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661095f565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60208260ff161115610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161058c565b6008820260006108808660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000806108f38385610ef8565b9050604051811115610903575060005b806000036109185762ffffff19915050610401565b5050606092831b9190911790911b1760181b90565b600061093f60048360ff16901c610aef565b60ff1661ffff919091161760081b61095682610aef565b60ff1617919050565b6060600061096c8661060a565b915050600061097a8661060a565b91505060006109888661060a565b91505060006109968661060a565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b600060f08083179060ff82169003610b0a5750603092915050565b8060ff1660f103610b1e5750603192915050565b8060ff1660f203610b325750603292915050565b8060ff1660f303610b465750603392915050565b8060ff1660f403610b5a5750603492915050565b8060ff1660f503610b6e5750603592915050565b8060ff1660f603610b825750603692915050565b8060ff1660f703610b965750603792915050565b8060ff1660f803610baa5750603892915050565b8060ff1660f903610bbe5750603992915050565b8060ff1660fa03610bd25750606192915050565b8060ff1660fb03610be65750606292915050565b8060ff1660fc03610bfa5750606392915050565b8060ff1660fd03610c0e5750606492915050565b8060ff1660fe03610c225750606592915050565b8060ff1660ff0361038a5750606692915050565b600060208284031215610c4857600080fd5b813562ffffff198116811461040157600080fd5b6000815180845260005b81811015610c8257602081850181015186830182015201610c66565b81811115610c94576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104016020830184610c5c565b80356bffffffffffffffffffffffff81168114610cf657600080fd5b919050565b60008060008060808587031215610d1157600080fd5b610d1a85610cda565b9350610d2860208601610cda565b9250610d3660408601610cda565b9150610d4460608601610cda565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610d9057600080fd5b813567ffffffffffffffff80821115610da857600080fd5b818401915084601f830112610dbc57600080fd5b813581811115610dce57610dce610d4f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610e1457610e14610d4f565b81604052828152876020848701011115610e2d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516808303821115610ea357610ea3610e4d565b01949350505050565b600060ff821660ff841680821015610ec657610ec6610e4d565b90039392505050565b600060ff821660ff84168160ff0481118215151615610ef057610ef0610e4d565b029392505050565b60008219821115610f0b57610f0b610e4d565b50019056fea264697066735822122080bb2f0dd7388e611e68ce74f6b5890ed877223fd854efebd4f22488452dab8e64736f6c634300080d0033", + Bin: "0x608060405234801561001057600080fd5b50610f46806100206000396000f3fe608060405234801561001057600080fd5b50600436106100e95760003560e01c8063918648051161008c578063c46647e211610066578063c46647e2146101ad578063cc6a5c9b146101c0578063d024f867146101d3578063ec000108146101e657600080fd5b8063918648051461018057806398de855414610193578063aa02b2b21461019a57600080fd5b806360fb5709116100c857806360fb57091461013b5780637137088914610151578063725bd463146101585780638ff916f81461016d57600080fd5b806232b444146100ee57806301fab8df146101045780631c9caa041461010b575b600080fd5b600e5b6040519081526020015b60405180910390f35b60266100f1565b61011e610119366004610c36565b61020e565b6040516bffffffffffffffffffffffff90911681526020016100fb565b60015b60405161ffff90911681526020016100fb565b60026100f1565b61016061021f565b6040516100fb9190610cc7565b61011e61017b366004610c36565b610283565b61011e61018e366004610c36565b61028e565b601a6100f1565b61011e6101a8366004610c36565b610299565b61013e6101bb366004610c36565b6102a4565b61011e6101ce366004610c36565b6102af565b6101606101e1366004610cfb565b6102ba565b6101f96101f4366004610d7e565b61034c565b60405162ffffff1990911681526020016100fb565b600061021982610357565b92915050565b606061027e604080517e010000000000000000000000000000000000000000000000000000000000006020820152600060228201819052602e8201819052603a8201819052604682015281518082036032018152605290910190915290565b905090565b600061021982610390565b6000610219826103b1565b600061021982610408565b600061021982610429565b60006102198261044a565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a087811b8216602284015286811b8216602e84015285811b8216603a84015284901b1660468201528151808203603201815260529091019091526060905b95945050505050565b60006102198261046b565b60008161036d60025b62ffffff19831690610478565b5061038162ffffff1984166026600c61059c565b63ffffffff1691505b50919050565b60008161039d6002610360565b5061038162ffffff1984166002600c61059c565b6000816103be6002610360565b506103c883610357565b6103d18461044a565b6103da85610408565b6103e386610390565b6103ed9190610e7c565b6103f79190610e7c565b6104019190610e7c565b9392505050565b6000816104156002610360565b5061038162ffffff198416600e600c61059c565b6000816104366002610360565b5061040162ffffff1984166000600261059c565b6000816104576002610360565b5061038162ffffff198416601a600c61059c565b60006102198260026105cc565b600061048483836105e7565b6105955760006104a36104978560d81c90565b64ffffffffff1661060a565b91505060006104b88464ffffffffff1661060a565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60405180910390fd5b5090919050565b60006105a9826020610eac565b6105b4906008610ecf565b60ff166105c28585856106f4565b901c949350505050565b81516000906020840161034364ffffffffff851682846108e6565b60008164ffffffffff166105fb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561067d576000610629826008610ecf565b60ff1685901c905061063a8161092d565b61ffff16841793508160ff1660101461065557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610610565b50600f5b60ff8160ff1610156106ee57600061069a826008610ecf565b60ff1685901c90506106ab8161092d565b61ffff16831792508160ff166000146106c657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610681565b50915091565b60008160ff1660000361070957506000610401565b6107218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661073c60ff841685610ef8565b11156107ce5761079b61075d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166107838660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661095f565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60208260ff161115610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161058c565b6008820260006108808660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000806108f38385610ef8565b9050604051811115610903575060005b806000036109185762ffffff19915050610401565b5050606092831b9190911790911b1760181b90565b600061093f60048360ff16901c610aef565b60ff1661ffff919091161760081b61095682610aef565b60ff1617919050565b6060600061096c8661060a565b915050600061097a8661060a565b91505060006109888661060a565b91505060006109968661060a565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b600060f08083179060ff82169003610b0a5750603092915050565b8060ff1660f103610b1e5750603192915050565b8060ff1660f203610b325750603292915050565b8060ff1660f303610b465750603392915050565b8060ff1660f403610b5a5750603492915050565b8060ff1660f503610b6e5750603592915050565b8060ff1660f603610b825750603692915050565b8060ff1660f703610b965750603792915050565b8060ff1660f803610baa5750603892915050565b8060ff1660f903610bbe5750603992915050565b8060ff1660fa03610bd25750606192915050565b8060ff1660fb03610be65750606292915050565b8060ff1660fc03610bfa5750606392915050565b8060ff1660fd03610c0e5750606492915050565b8060ff1660fe03610c225750606592915050565b8060ff1660ff0361038a5750606692915050565b600060208284031215610c4857600080fd5b813562ffffff198116811461040157600080fd5b6000815180845260005b81811015610c8257602081850181015186830182015201610c66565b81811115610c94576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104016020830184610c5c565b80356bffffffffffffffffffffffff81168114610cf657600080fd5b919050565b60008060008060808587031215610d1157600080fd5b610d1a85610cda565b9350610d2860208601610cda565b9250610d3660408601610cda565b9150610d4460608601610cda565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610d9057600080fd5b813567ffffffffffffffff80821115610da857600080fd5b818401915084601f830112610dbc57600080fd5b813581811115610dce57610dce610d4f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610e1457610e14610d4f565b81604052828152876020848701011115610e2d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516808303821115610ea357610ea3610e4d565b01949350505050565b600060ff821660ff841680821015610ec657610ec6610e4d565b90039392505050565b600060ff821660ff84168160ff0481118215151615610ef057610ef0610e4d565b029392505050565b60008219821115610f0b57610f0b610e4d565b50019056fea26469706673582212208f255dfec8ffaa1926c97ec49cbec9b3afdeb220c5461d83959ed30acf3bb86e64736f6c634300080d0033", } // TipsHarnessABI is the input ABI used to generate the binding from. @@ -1177,7 +1177,7 @@ func (_TipsHarness *TipsHarnessCallerSession) UpdaterTip(_tips [29]byte) (*big.I // TypeCastsMetaData contains all meta data concerning the TypeCasts contract. var TypeCastsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209d4dabeedf95335317103634a9c53a2a22fda3b1e08e995029f05dd8d27930ca64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207a4a829a4ff4787148001272e92eb978a36314f1e5fb49597cce4efaf4118a2064736f6c634300080d0033", } // TypeCastsABI is the input ABI used to generate the binding from. @@ -1353,7 +1353,7 @@ var TypedMemViewMetaData = &bind.MetaData{ Sigs: map[string]string{ "f26be3fc": "NULL()", }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212206a332c8de003a933b7360299572396470083afeabb4e7897ff348b8cb529b5bb64736f6c634300080d0033", + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122078c50a2fa8be8f96b424fd97322fe02bd9fbb184e917c2c74eaea55a9edfa96764736f6c634300080d0033", } // TypedMemViewABI is the input ABI used to generate the binding from. diff --git a/core/contracts/test/tipsharness/tipsharness.contractinfo.json b/core/contracts/test/tipsharness/tipsharness.contractinfo.json index ccfb81f630..b2048dc8cc 100644 --- a/core/contracts/test/tipsharness/tipsharness.contractinfo.json +++ b/core/contracts/test/tipsharness/tipsharness.contractinfo.json @@ -1 +1 @@ -{"solidity/TipsHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220167fb68c855f9d771928b270486ee53bdcab38b844708f0dbf70226009ffadd964736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220167fb68c855f9d771928b270486ee53bdcab38b844708f0dbf70226009ffadd964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n*/\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33386:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33386:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33386:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x4c9133d42ff8dfea2b81d691deac82b23b64a9f3988b78b3cefbc5fe9e52ec42\",\"urls\":[\"bzz-raw://e68a5c37a35b8ad64d33ba582c2952414d206c94cbd38788a2ddbf439b65dd8e\",\"dweb:/ipfs/Qmbz58CM6tM1A4HtsMCNmfKKcbaY5jZtMQ9i4sW2zWUhiZ\"]}},\"version\":1}"},"hashes":{}},"solidity/TipsHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206d6e95f83e9c6348bfd4e4725fa30f7e844bf8bf4a80949347662bc32525e74e64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212206d6e95f83e9c6348bfd4e4725fa30f7e844bf8bf4a80949347662bc32525e74e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n*/\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"36691:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;36691:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"36691:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x4c9133d42ff8dfea2b81d691deac82b23b64a9f3988b78b3cefbc5fe9e52ec42\",\"urls\":[\"bzz-raw://e68a5c37a35b8ad64d33ba582c2952414d206c94cbd38788a2ddbf439b65dd8e\",\"dweb:/ipfs/Qmbz58CM6tM1A4HtsMCNmfKKcbaY5jZtMQ9i4sW2zWUhiZ\"]}},\"version\":1}"},"hashes":{}},"solidity/TipsHarness.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220054f1d90244b4e1f649d7b1f810440c4af932c944e591f693a79040e1035dbf364736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220054f1d90244b4e1f649d7b1f810440c4af932c944e591f693a79040e1035dbf364736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n*/\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"41664:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;41664:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"41664:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x4c9133d42ff8dfea2b81d691deac82b23b64a9f3988b78b3cefbc5fe9e52ec42\",\"urls\":[\"bzz-raw://e68a5c37a35b8ad64d33ba582c2952414d206c94cbd38788a2ddbf439b65dd8e\",\"dweb:/ipfs/Qmbz58CM6tM1A4HtsMCNmfKKcbaY5jZtMQ9i4sW2zWUhiZ\"]}},\"version\":1}"},"hashes":{}},"solidity/TipsHarness.sol:TipsHarness":{"code":"0x608060405234801561001057600080fd5b50610f46806100206000396000f3fe608060405234801561001057600080fd5b50600436106100e95760003560e01c8063918648051161008c578063c46647e211610066578063c46647e2146101ad578063cc6a5c9b146101c0578063d024f867146101d3578063ec000108146101e657600080fd5b8063918648051461018057806398de855414610193578063aa02b2b21461019a57600080fd5b806360fb5709116100c857806360fb57091461013b5780637137088914610151578063725bd463146101585780638ff916f81461016d57600080fd5b806232b444146100ee57806301fab8df146101045780631c9caa041461010b575b600080fd5b600e5b6040519081526020015b60405180910390f35b60266100f1565b61011e610119366004610c36565b61020e565b6040516bffffffffffffffffffffffff90911681526020016100fb565b60015b60405161ffff90911681526020016100fb565b60026100f1565b61016061021f565b6040516100fb9190610cc7565b61011e61017b366004610c36565b610283565b61011e61018e366004610c36565b61028e565b601a6100f1565b61011e6101a8366004610c36565b610299565b61013e6101bb366004610c36565b6102a4565b61011e6101ce366004610c36565b6102af565b6101606101e1366004610cfb565b6102ba565b6101f96101f4366004610d7e565b61034c565b60405162ffffff1990911681526020016100fb565b600061021982610357565b92915050565b606061027e604080517e010000000000000000000000000000000000000000000000000000000000006020820152600060228201819052602e8201819052603a8201819052604682015281518082036032018152605290910190915290565b905090565b600061021982610390565b6000610219826103b1565b600061021982610408565b600061021982610429565b60006102198261044a565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a087811b8216602284015286811b8216602e84015285811b8216603a84015284901b1660468201528151808203603201815260529091019091526060905b95945050505050565b60006102198261046b565b60008161036d60025b62ffffff19831690610478565b5061038162ffffff1984166026600c61059c565b63ffffffff1691505b50919050565b60008161039d6002610360565b5061038162ffffff1984166002600c61059c565b6000816103be6002610360565b506103c883610357565b6103d18461044a565b6103da85610408565b6103e386610390565b6103ed9190610e7c565b6103f79190610e7c565b6104019190610e7c565b9392505050565b6000816104156002610360565b5061038162ffffff198416600e600c61059c565b6000816104366002610360565b5061040162ffffff1984166000600261059c565b6000816104576002610360565b5061038162ffffff198416601a600c61059c565b60006102198260026105cc565b600061048483836105e7565b6105955760006104a36104978560d81c90565b64ffffffffff1661060a565b91505060006104b88464ffffffffff1661060a565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60405180910390fd5b5090919050565b60006105a9826020610eac565b6105b4906008610ecf565b60ff166105c28585856106f4565b901c949350505050565b81516000906020840161034364ffffffffff851682846108e6565b60008164ffffffffff166105fb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561067d576000610629826008610ecf565b60ff1685901c905061063a8161092d565b61ffff16841793508160ff1660101461065557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610610565b50600f5b60ff8160ff1610156106ee57600061069a826008610ecf565b60ff1685901c90506106ab8161092d565b61ffff16831792508160ff166000146106c657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610681565b50915091565b60008160ff1660000361070957506000610401565b6107218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661073c60ff841685610ef8565b11156107ce5761079b61075d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166107838660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661095f565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60208260ff161115610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161058c565b6008820260006108808660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000806108f38385610ef8565b9050604051811115610903575060005b806000036109185762ffffff19915050610401565b5050606092831b9190911790911b1760181b90565b600061093f60048360ff16901c610aef565b60ff1661ffff919091161760081b61095682610aef565b60ff1617919050565b6060600061096c8661060a565b915050600061097a8661060a565b91505060006109888661060a565b91505060006109968661060a565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b600060f08083179060ff82169003610b0a5750603092915050565b8060ff1660f103610b1e5750603192915050565b8060ff1660f203610b325750603292915050565b8060ff1660f303610b465750603392915050565b8060ff1660f403610b5a5750603492915050565b8060ff1660f503610b6e5750603592915050565b8060ff1660f603610b825750603692915050565b8060ff1660f703610b965750603792915050565b8060ff1660f803610baa5750603892915050565b8060ff1660f903610bbe5750603992915050565b8060ff1660fa03610bd25750606192915050565b8060ff1660fb03610be65750606292915050565b8060ff1660fc03610bfa5750606392915050565b8060ff1660fd03610c0e5750606492915050565b8060ff1660fe03610c225750606592915050565b8060ff1660ff0361038a5750606692915050565b600060208284031215610c4857600080fd5b813562ffffff198116811461040157600080fd5b6000815180845260005b81811015610c8257602081850181015186830182015201610c66565b81811115610c94576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104016020830184610c5c565b80356bffffffffffffffffffffffff81168114610cf657600080fd5b919050565b60008060008060808587031215610d1157600080fd5b610d1a85610cda565b9350610d2860208601610cda565b9250610d3660408601610cda565b9150610d4460608601610cda565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610d9057600080fd5b813567ffffffffffffffff80821115610da857600080fd5b818401915084601f830112610dbc57600080fd5b813581811115610dce57610dce610d4f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610e1457610e14610d4f565b81604052828152876020848701011115610e2d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516808303821115610ea357610ea3610e4d565b01949350505050565b600060ff821660ff841680821015610ec657610ec6610e4d565b90039392505050565b600060ff821660ff84168160ff0481118215151615610ef057610ef0610e4d565b029392505050565b60008219821115610f0b57610f0b610e4d565b50019056fea264697066735822122080bb2f0dd7388e611e68ce74f6b5890ed877223fd854efebd4f22488452dab8e64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100e95760003560e01c8063918648051161008c578063c46647e211610066578063c46647e2146101ad578063cc6a5c9b146101c0578063d024f867146101d3578063ec000108146101e657600080fd5b8063918648051461018057806398de855414610193578063aa02b2b21461019a57600080fd5b806360fb5709116100c857806360fb57091461013b5780637137088914610151578063725bd463146101585780638ff916f81461016d57600080fd5b806232b444146100ee57806301fab8df146101045780631c9caa041461010b575b600080fd5b600e5b6040519081526020015b60405180910390f35b60266100f1565b61011e610119366004610c36565b61020e565b6040516bffffffffffffffffffffffff90911681526020016100fb565b60015b60405161ffff90911681526020016100fb565b60026100f1565b61016061021f565b6040516100fb9190610cc7565b61011e61017b366004610c36565b610283565b61011e61018e366004610c36565b61028e565b601a6100f1565b61011e6101a8366004610c36565b610299565b61013e6101bb366004610c36565b6102a4565b61011e6101ce366004610c36565b6102af565b6101606101e1366004610cfb565b6102ba565b6101f96101f4366004610d7e565b61034c565b60405162ffffff1990911681526020016100fb565b600061021982610357565b92915050565b606061027e604080517e010000000000000000000000000000000000000000000000000000000000006020820152600060228201819052602e8201819052603a8201819052604682015281518082036032018152605290910190915290565b905090565b600061021982610390565b6000610219826103b1565b600061021982610408565b600061021982610429565b60006102198261044a565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a087811b8216602284015286811b8216602e84015285811b8216603a84015284901b1660468201528151808203603201815260529091019091526060905b95945050505050565b60006102198261046b565b60008161036d60025b62ffffff19831690610478565b5061038162ffffff1984166026600c61059c565b63ffffffff1691505b50919050565b60008161039d6002610360565b5061038162ffffff1984166002600c61059c565b6000816103be6002610360565b506103c883610357565b6103d18461044a565b6103da85610408565b6103e386610390565b6103ed9190610e7c565b6103f79190610e7c565b6104019190610e7c565b9392505050565b6000816104156002610360565b5061038162ffffff198416600e600c61059c565b6000816104366002610360565b5061040162ffffff1984166000600261059c565b6000816104576002610360565b5061038162ffffff198416601a600c61059c565b60006102198260026105cc565b600061048483836105e7565b6105955760006104a36104978560d81c90565b64ffffffffff1661060a565b91505060006104b88464ffffffffff1661060a565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60405180910390fd5b5090919050565b60006105a9826020610eac565b6105b4906008610ecf565b60ff166105c28585856106f4565b901c949350505050565b81516000906020840161034364ffffffffff851682846108e6565b60008164ffffffffff166105fb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561067d576000610629826008610ecf565b60ff1685901c905061063a8161092d565b61ffff16841793508160ff1660101461065557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610610565b50600f5b60ff8160ff1610156106ee57600061069a826008610ecf565b60ff1685901c90506106ab8161092d565b61ffff16831792508160ff166000146106c657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610681565b50915091565b60008160ff1660000361070957506000610401565b6107218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661073c60ff841685610ef8565b11156107ce5761079b61075d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166107838660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661095f565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60208260ff161115610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161058c565b6008820260006108808660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000806108f38385610ef8565b9050604051811115610903575060005b806000036109185762ffffff19915050610401565b5050606092831b9190911790911b1760181b90565b600061093f60048360ff16901c610aef565b60ff1661ffff919091161760081b61095682610aef565b60ff1617919050565b6060600061096c8661060a565b915050600061097a8661060a565b91505060006109888661060a565b91505060006109968661060a565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b600060f08083179060ff82169003610b0a5750603092915050565b8060ff1660f103610b1e5750603192915050565b8060ff1660f203610b325750603292915050565b8060ff1660f303610b465750603392915050565b8060ff1660f403610b5a5750603492915050565b8060ff1660f503610b6e5750603592915050565b8060ff1660f603610b825750603692915050565b8060ff1660f703610b965750603792915050565b8060ff1660f803610baa5750603892915050565b8060ff1660f903610bbe5750603992915050565b8060ff1660fa03610bd25750606192915050565b8060ff1660fb03610be65750606292915050565b8060ff1660fc03610bfa5750606392915050565b8060ff1660fd03610c0e5750606492915050565b8060ff1660fe03610c225750606592915050565b8060ff1660ff0361038a5750606692915050565b600060208284031215610c4857600080fd5b813562ffffff198116811461040157600080fd5b6000815180845260005b81811015610c8257602081850181015186830182015201610c66565b81811115610c94576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104016020830184610c5c565b80356bffffffffffffffffffffffff81168114610cf657600080fd5b919050565b60008060008060808587031215610d1157600080fd5b610d1a85610cda565b9350610d2860208601610cda565b9250610d3660408601610cda565b9150610d4460608601610cda565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610d9057600080fd5b813567ffffffffffffffff80821115610da857600080fd5b818401915084601f830112610dbc57600080fd5b813581811115610dce57610dce610d4f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610e1457610e14610d4f565b81604052828152876020848701011115610e2d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516808303821115610ea357610ea3610e4d565b01949350505050565b600060ff821660ff841680821015610ec657610ec6610e4d565b90039392505050565b600060ff821660ff84168160ff0481118215151615610ef057610ef0610e4d565b029392505050565b60008219821115610f0b57610f0b610e4d565b50019056fea264697066735822122080bb2f0dd7388e611e68ce74f6b5890ed877223fd854efebd4f22488452dab8e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n*/\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44735:1966:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"44735:1966:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45020:98;42223:2;45020:98;;;160:25:1;;;148:2;133:18;45020:98:0;;;;;;;;45226:102;42326:2;45226:102;;46467:116;;;;;;:::i;:::-;;:::i;:::-;;;708:26:1;696:39;;;678:58;;666:2;651:18;46467:116:0;534:208:1;44817:93:0;41794:1;44817:93;;;921:6:1;909:19;;;891:38;;879:2;864:18;44817:93:0;747:188:1;44916:98:0;42173:1;44916:98;;45606;;;:::i;:::-;;;;;;;:::i;45991:112::-;;;;;;:::i;:::-;;:::i;46589:110::-;;;;;;:::i;:::-;;:::i;45124:96::-;42273:2;45124:96;;46150:112;;;;;;:::i;:::-;;:::i;45830:114::-;;;;;;:::i;:::-;;:::i;46308:110::-;;;;;;:::i;:::-;;:::i;45334:266::-;;;;;;:::i;:::-;;:::i;45710:114::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;3625:79:1;;;3607:98;;3595:2;3580:18;45710:114:0;3461:250:1;46467:116:0;46527:6;46552:24;46570:5;46552:17;:24::i;:::-;46545:31;46467:116;-1:-1:-1;;46467:116:0:o;45606:98::-;45650:12;45681:16;42931:83;;;4590:16:1;42931:83:0;;;4574:102:1;43204:1:0;4777:11:1;;;4770:46;;;4832:12;;;4825:47;;;4888:12;;;4881:47;;;4944:12;;;4937:47;42931:83:0;;;;;;;;;5000:12:1;;;;42931:83:0;;;45606:98;;45681:16;45674:23;;45606:98;:::o;45991:112::-;46049:6;46074:22;46090:5;46074:15;:22::i;46589:110::-;46646:6;46671:21;46686:5;46671:14;:21::i;46150:112::-;46208:6;46233:22;46249:5;46233:15;:22::i;45830:114::-;45889:6;45914:23;45931:5;45914:16;:23::i;46308:110::-;46365:6;46390:21;46405:5;46390:14;:21::i;45334:266::-;42931:83;;;4590:16:1;42931:83:0;;;4574:102:1;4695:66;4798:3;4794:16;;;4790:25;;4777:11;;;4770:46;4850:16;;;4846:25;;4832:12;;;4825:47;4906:16;;;4902:25;;4888:12;;;4881:47;4962:16;;;4958:25;4944:12;;;4937:47;42931:83:0;;;;;;;;;5000:12:1;;;;42931:83:0;;;45494:12;;45525:68;45518:75;45334:266;-1:-1:-1;;;;;45334:266:0:o;45710:114::-;45771:7;45797:20;45811:5;45797:13;:20::i;44319:153::-;44395:6;44379:5;42378:35;37393:10;37386:18;-1:-1:-1;;42378:16:0;;;;:35::i;:::-;-1:-1:-1;44427:37:0::1;-1:-1:-1::0;;44427:15:0;::::1;42326:2;44461;44427:15;:37::i;:::-;44413:52;;;;42423:1;44319:153:::0;;;;:::o;43732:149::-;43806:6;43790:5;42378:35;37393:10;37386:18;;42378:35;-1:-1:-1;43838:35:0::1;-1:-1:-1::0;;43838:15:0;::::1;42173:1;43870:2;43838:15;:35::i;44478:183::-:0;44551:6;44535:5;42378:35;37393:10;37386:18;;42378:35;;44635:19:::1;44648:5;44635:12;:19::i;:::-;44616:16;44626:5;44616:9;:16::i;:::-;44596:17;44607:5;44596:10;:17::i;:::-;44576;44587:5;44576:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;44569:85:::0;44478:183;-1:-1:-1;;;44478:183:0:o;43928:149::-;44002:6;43986:5;42378:35;37393:10;37386:18;;42378:35;-1:-1:-1;44034:35:0::1;-1:-1:-1::0;;44034:15:0;::::1;42223:2;44066;44034:15;:35::i;43549:136::-:0;43624:6;43608:5;42378:35;37393:10;37386:18;;42378:35;-1:-1:-1;43656:21:0::1;-1:-1:-1::0;;43656:15:0;::::1;43672:1;43675;43656:15;:21::i;44123:147::-:0;44196:6;44180:5;42378:35;37393:10;37386:18;;42378:35;-1:-1:-1;44228:34:0::1;-1:-1:-1::0;;44228:15:0;::::1;42273:2;44259;44228:15;:34::i;43371:122::-:0;43432:7;43458:28;:5;37393:10;43458:9;:28::i;10073:578::-;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;5390:31:1;10385:186:0;;;5378:44:1;5441:66;5545:3;5541:16;;;5537:25;;5523:12;;;5516:47;5593:15;5579:12;;;5572:37;5643:16;;;5639:25;5625:12;;;5618:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;5681:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;;;;;;;;;;:::i;:::-;;;;;;;;10170:451;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;13655:359::-;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;;;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;;;;6706:2:1;20359:83:0;;;6688:21:1;6745:2;6725:18;;;6718:30;6784:34;6764:18;;;6757:62;6855:28;6835:18;;;6828:56;6901:19;;20359:83:0;6504:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;12796:462::-;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;-1:-1:-1;;12065:2:0;12061:27;;;12135:17;;;;12127:26;;;12199:17;12195:2;12191:26;;12796:462::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19130:355;;;7772:34:1;19130:355:0;;;7760:47:1;7837:23;7823:12;;;7816:45;7880:66;7984:3;7980:16;;;7976:25;;7962:12;;;7955:47;8021:17;8054:12;;;8047:24;;;8105:16;;;8101:25;;8087:12;;;8080:47;8157:34;8143:12;;;8136:56;8223:3;8208:13;;;8201:26;8262:16;;;8258:25;;8243:13;;;8236:48;8300:13;;;8293:25;;;;8353:16;;8349:25;;;8334:13;;;8327:48;-1:-1:-1;;7008:3:1;8421:13;;;6996:16;19130:355:0;;;;;;;;;7028:11:1;;;;19130:355:0;;;;;-1:-1:-1;;;;;18761:741:0:o;2943:1393::-;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;196:333:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;363:9;350:23;-1:-1:-1;;406:5:1;402:78;395:5;392:89;382:117;;495:1;492;485:12;940:530;981:3;1019:5;1013:12;1046:6;1041:3;1034:19;1071:1;1081:162;1095:6;1092:1;1089:13;1081:162;;;1157:4;1213:13;;;1209:22;;1203:29;1185:11;;;1181:20;;1174:59;1110:12;1081:162;;;1261:6;1258:1;1255:13;1252:87;;;1327:1;1320:4;1311:6;1306:3;1302:16;1298:27;1291:38;1252:87;-1:-1:-1;1384:2:1;1372:15;1389:66;1368:88;1359:98;;;;1459:4;1355:109;;940:530;-1:-1:-1;;940:530:1:o;1475:217::-;1622:2;1611:9;1604:21;1585:4;1642:44;1682:2;1671:9;1667:18;1659:6;1642:44;:::i;1697:179::-;1764:20;;1824:26;1813:38;;1803:49;;1793:77;;1866:1;1863;1856:12;1793:77;1697:179;;;:::o;1881:401::-;1963:6;1971;1979;1987;2040:3;2028:9;2019:7;2015:23;2011:33;2008:53;;;2057:1;2054;2047:12;2008:53;2080:28;2098:9;2080:28;:::i;:::-;2070:38;;2127:37;2160:2;2149:9;2145:18;2127:37;:::i;:::-;2117:47;;2183:37;2216:2;2205:9;2201:18;2183:37;:::i;:::-;2173:47;;2239:37;2272:2;2261:9;2257:18;2239:37;:::i;:::-;2229:47;;1881:401;;;;;;;:::o;2287:184::-;2339:77;2336:1;2329:88;2436:4;2433:1;2426:15;2460:4;2457:1;2450:15;2476:980;2544:6;2597:2;2585:9;2576:7;2572:23;2568:32;2565:52;;;2613:1;2610;2603:12;2565:52;2653:9;2640:23;2682:18;2723:2;2715:6;2712:14;2709:34;;;2739:1;2736;2729:12;2709:34;2777:6;2766:9;2762:22;2752:32;;2822:7;2815:4;2811:2;2807:13;2803:27;2793:55;;2844:1;2841;2834:12;2793:55;2880:2;2867:16;2902:2;2898;2895:10;2892:36;;;2908:18;;:::i;:::-;3042:2;3036:9;3104:4;3096:13;;2947:66;3092:22;;;3116:2;3088:31;3084:40;3072:53;;;3140:18;;;3160:22;;;3137:46;3134:72;;;3186:18;;:::i;:::-;3226:10;3222:2;3215:22;3261:2;3253:6;3246:18;3301:7;3296:2;3291;3287;3283:11;3279:20;3276:33;3273:53;;;3322:1;3319;3312:12;3273:53;3378:2;3373;3369;3365:11;3360:2;3352:6;3348:15;3335:46;3423:1;3401:15;;;3418:2;3397:24;3390:35;;;;-1:-1:-1;3405:6:1;2476:980;-1:-1:-1;;;;;2476:980:1:o;3905:184::-;3957:77;3954:1;3947:88;4054:4;4051:1;4044:15;4078:4;4075:1;4068:15;4094:244;4133:3;4161:26;4214:2;4211:1;4207:10;4244:2;4241:1;4237:10;4275:3;4271:2;4267:12;4262:3;4259:21;4256:47;;;4283:18;;:::i;:::-;4319:13;;4094:244;-1:-1:-1;;;;4094:244:1:o;5928:195::-;5966:4;6003;6000:1;5996:12;6035:4;6032:1;6028:12;6060:3;6055;6052:12;6049:38;;;6067:18;;:::i;:::-;6104:13;;;5928:195;-1:-1:-1;;;5928:195:1:o;6128:238::-;6166:7;6206:4;6203:1;6199:12;6238:4;6235:1;6231:12;6298:3;6292:4;6288:14;6283:3;6280:23;6273:3;6266:11;6259:19;6255:49;6252:75;;;6307:18;;:::i;:::-;6347:13;;6128:238;-1:-1:-1;;;6128:238:1:o;6371:128::-;6411:3;6442:1;6438:6;6435:1;6432:13;6429:39;;;6448:18;;:::i;:::-;-1:-1:-1;6484:9:1;;6371:128::o","abiDefinition":[{"inputs":[],"name":"emptyTips","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint96","name":"_updaterTip","type":"uint96"},{"internalType":"uint96","name":"_relayerTip","type":"uint96"},{"internalType":"uint96","name":"_proverTip","type":"uint96"},{"internalType":"uint96","name":"_processorTip","type":"uint96"}],"name":"formatTips","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetProcessor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetProver","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetRelayer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetUpdater","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"processorTip","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"proverTip","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"relayerTip","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"tipsVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"tipsVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_tips","type":"bytes"}],"name":"tipsView","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"totalTips","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"updaterTip","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"}],"userDoc":{"kind":"user","methods":{"processorTip(bytes29)":{"notice":"Returns processorTip field"},"proverTip(bytes29)":{"notice":"Returns proverTip field"},"relayerTip(bytes29)":{"notice":"Returns relayerTip field"},"updaterTip(bytes29)":{"notice":"Returns updaterTip field"}},"notice":"exposes tips methods for testing against golang","version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"emptyTips\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"_updaterTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_relayerTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_proverTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_processorTip\",\"type\":\"uint96\"}],\"name\":\"formatTips\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetProcessor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetProver\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetRelayer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetUpdater\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"processorTip\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"proverTip\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"relayerTip\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tipsVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"tipsVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"}],\"name\":\"tipsView\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"totalTips\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"updaterTip\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"processorTip(bytes29)\":{\"notice\":\"Returns processorTip field\"},\"proverTip(bytes29)\":{\"notice\":\"Returns proverTip field\"},\"relayerTip(bytes29)\":{\"notice\":\"Returns relayerTip field\"},\"updaterTip(bytes29)\":{\"notice\":\"Returns updaterTip field\"}},\"notice\":\"exposes tips methods for testing against golang\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"TipsHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x4c9133d42ff8dfea2b81d691deac82b23b64a9f3988b78b3cefbc5fe9e52ec42\",\"urls\":[\"bzz-raw://e68a5c37a35b8ad64d33ba582c2952414d206c94cbd38788a2ddbf439b65dd8e\",\"dweb:/ipfs/Qmbz58CM6tM1A4HtsMCNmfKKcbaY5jZtMQ9i4sW2zWUhiZ\"]}},\"version\":1}"},"hashes":{"emptyTips()":"725bd463","formatTips(uint96,uint96,uint96,uint96)":"d024f867","offsetProcessor()":"01fab8df","offsetProver()":"98de8554","offsetRelayer()":"0032b444","offsetUpdater()":"71370889","processorTip(bytes29)":"1c9caa04","proverTip(bytes29)":"cc6a5c9b","relayerTip(bytes29)":"aa02b2b2","tipsVersion()":"60fb5709","tipsVersion(bytes29)":"c46647e2","tipsView(bytes)":"ec000108","totalTips(bytes29)":"91864805","updaterTip(bytes29)":"8ff916f8"}},"solidity/TipsHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209d4dabeedf95335317103634a9c53a2a22fda3b1e08e995029f05dd8d27930ca64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209d4dabeedf95335317103634a9c53a2a22fda3b1e08e995029f05dd8d27930ca64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n*/\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32274:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32274:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32274:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x4c9133d42ff8dfea2b81d691deac82b23b64a9f3988b78b3cefbc5fe9e52ec42\",\"urls\":[\"bzz-raw://e68a5c37a35b8ad64d33ba582c2952414d206c94cbd38788a2ddbf439b65dd8e\",\"dweb:/ipfs/Qmbz58CM6tM1A4HtsMCNmfKKcbaY5jZtMQ9i4sW2zWUhiZ\"]}},\"version\":1}"},"hashes":{}},"solidity/TipsHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212206a332c8de003a933b7360299572396470083afeabb4e7897ff348b8cb529b5bb64736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea26469706673582212206a332c8de003a933b7360299572396470083afeabb4e7897ff348b8cb529b5bb64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n*/\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x4c9133d42ff8dfea2b81d691deac82b23b64a9f3988b78b3cefbc5fe9e52ec42\",\"urls\":[\"bzz-raw://e68a5c37a35b8ad64d33ba582c2952414d206c94cbd38788a2ddbf439b65dd8e\",\"dweb:/ipfs/Qmbz58CM6tM1A4HtsMCNmfKKcbaY5jZtMQ9i4sW2zWUhiZ\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}}} \ No newline at end of file +{"solidity/TipsHarness.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205365420036cda746eb8352956b3072ebeae2af69625c55afcc8e67104df4316464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205365420036cda746eb8352956b3072ebeae2af69625c55afcc8e67104df4316464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n */\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33386:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33386:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33386:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x1e84f57bd0ef3366dae1ca132da5b135ccbdc498c09418f92319847884b59028\",\"urls\":[\"bzz-raw://14fc1754929893ac24d22163e79f0bfded428449ed815cd8d06443c37fa211c9\",\"dweb:/ipfs/QmUBZuHuxiAnpJ6G5tbBvTjsCP9yLsQ9QPbTgpARk2FbE4\"]}},\"version\":1}"},"hashes":{}},"solidity/TipsHarness.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220197ca01069b17f5799ef5da3d241af37ec5800195e5180d76bfa64701a739b3564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220197ca01069b17f5799ef5da3d241af37ec5800195e5180d76bfa64701a739b3564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n */\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"36691:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;36691:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"36691:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x1e84f57bd0ef3366dae1ca132da5b135ccbdc498c09418f92319847884b59028\",\"urls\":[\"bzz-raw://14fc1754929893ac24d22163e79f0bfded428449ed815cd8d06443c37fa211c9\",\"dweb:/ipfs/QmUBZuHuxiAnpJ6G5tbBvTjsCP9yLsQ9QPbTgpARk2FbE4\"]}},\"version\":1}"},"hashes":{}},"solidity/TipsHarness.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220afc6e3c028c4a3ba975d2e5743574dc8ea4e4a296d7c25af1359472490ce8ac564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220afc6e3c028c4a3ba975d2e5743574dc8ea4e4a296d7c25af1359472490ce8ac564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n */\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"41664:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;41664:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"41664:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x1e84f57bd0ef3366dae1ca132da5b135ccbdc498c09418f92319847884b59028\",\"urls\":[\"bzz-raw://14fc1754929893ac24d22163e79f0bfded428449ed815cd8d06443c37fa211c9\",\"dweb:/ipfs/QmUBZuHuxiAnpJ6G5tbBvTjsCP9yLsQ9QPbTgpARk2FbE4\"]}},\"version\":1}"},"hashes":{}},"solidity/TipsHarness.sol:TipsHarness":{"code":"0x608060405234801561001057600080fd5b50610f46806100206000396000f3fe608060405234801561001057600080fd5b50600436106100e95760003560e01c8063918648051161008c578063c46647e211610066578063c46647e2146101ad578063cc6a5c9b146101c0578063d024f867146101d3578063ec000108146101e657600080fd5b8063918648051461018057806398de855414610193578063aa02b2b21461019a57600080fd5b806360fb5709116100c857806360fb57091461013b5780637137088914610151578063725bd463146101585780638ff916f81461016d57600080fd5b806232b444146100ee57806301fab8df146101045780631c9caa041461010b575b600080fd5b600e5b6040519081526020015b60405180910390f35b60266100f1565b61011e610119366004610c36565b61020e565b6040516bffffffffffffffffffffffff90911681526020016100fb565b60015b60405161ffff90911681526020016100fb565b60026100f1565b61016061021f565b6040516100fb9190610cc7565b61011e61017b366004610c36565b610283565b61011e61018e366004610c36565b61028e565b601a6100f1565b61011e6101a8366004610c36565b610299565b61013e6101bb366004610c36565b6102a4565b61011e6101ce366004610c36565b6102af565b6101606101e1366004610cfb565b6102ba565b6101f96101f4366004610d7e565b61034c565b60405162ffffff1990911681526020016100fb565b600061021982610357565b92915050565b606061027e604080517e010000000000000000000000000000000000000000000000000000000000006020820152600060228201819052602e8201819052603a8201819052604682015281518082036032018152605290910190915290565b905090565b600061021982610390565b6000610219826103b1565b600061021982610408565b600061021982610429565b60006102198261044a565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a087811b8216602284015286811b8216602e84015285811b8216603a84015284901b1660468201528151808203603201815260529091019091526060905b95945050505050565b60006102198261046b565b60008161036d60025b62ffffff19831690610478565b5061038162ffffff1984166026600c61059c565b63ffffffff1691505b50919050565b60008161039d6002610360565b5061038162ffffff1984166002600c61059c565b6000816103be6002610360565b506103c883610357565b6103d18461044a565b6103da85610408565b6103e386610390565b6103ed9190610e7c565b6103f79190610e7c565b6104019190610e7c565b9392505050565b6000816104156002610360565b5061038162ffffff198416600e600c61059c565b6000816104366002610360565b5061040162ffffff1984166000600261059c565b6000816104576002610360565b5061038162ffffff198416601a600c61059c565b60006102198260026105cc565b600061048483836105e7565b6105955760006104a36104978560d81c90565b64ffffffffff1661060a565b91505060006104b88464ffffffffff1661060a565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60405180910390fd5b5090919050565b60006105a9826020610eac565b6105b4906008610ecf565b60ff166105c28585856106f4565b901c949350505050565b81516000906020840161034364ffffffffff851682846108e6565b60008164ffffffffff166105fb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561067d576000610629826008610ecf565b60ff1685901c905061063a8161092d565b61ffff16841793508160ff1660101461065557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610610565b50600f5b60ff8160ff1610156106ee57600061069a826008610ecf565b60ff1685901c90506106ab8161092d565b61ffff16831792508160ff166000146106c657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610681565b50915091565b60008160ff1660000361070957506000610401565b6107218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661073c60ff841685610ef8565b11156107ce5761079b61075d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166107838660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661095f565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60208260ff161115610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161058c565b6008820260006108808660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000806108f38385610ef8565b9050604051811115610903575060005b806000036109185762ffffff19915050610401565b5050606092831b9190911790911b1760181b90565b600061093f60048360ff16901c610aef565b60ff1661ffff919091161760081b61095682610aef565b60ff1617919050565b6060600061096c8661060a565b915050600061097a8661060a565b91505060006109888661060a565b91505060006109968661060a565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b600060f08083179060ff82169003610b0a5750603092915050565b8060ff1660f103610b1e5750603192915050565b8060ff1660f203610b325750603292915050565b8060ff1660f303610b465750603392915050565b8060ff1660f403610b5a5750603492915050565b8060ff1660f503610b6e5750603592915050565b8060ff1660f603610b825750603692915050565b8060ff1660f703610b965750603792915050565b8060ff1660f803610baa5750603892915050565b8060ff1660f903610bbe5750603992915050565b8060ff1660fa03610bd25750606192915050565b8060ff1660fb03610be65750606292915050565b8060ff1660fc03610bfa5750606392915050565b8060ff1660fd03610c0e5750606492915050565b8060ff1660fe03610c225750606592915050565b8060ff1660ff0361038a5750606692915050565b600060208284031215610c4857600080fd5b813562ffffff198116811461040157600080fd5b6000815180845260005b81811015610c8257602081850181015186830182015201610c66565b81811115610c94576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104016020830184610c5c565b80356bffffffffffffffffffffffff81168114610cf657600080fd5b919050565b60008060008060808587031215610d1157600080fd5b610d1a85610cda565b9350610d2860208601610cda565b9250610d3660408601610cda565b9150610d4460608601610cda565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610d9057600080fd5b813567ffffffffffffffff80821115610da857600080fd5b818401915084601f830112610dbc57600080fd5b813581811115610dce57610dce610d4f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610e1457610e14610d4f565b81604052828152876020848701011115610e2d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516808303821115610ea357610ea3610e4d565b01949350505050565b600060ff821660ff841680821015610ec657610ec6610e4d565b90039392505050565b600060ff821660ff84168160ff0481118215151615610ef057610ef0610e4d565b029392505050565b60008219821115610f0b57610f0b610e4d565b50019056fea26469706673582212208f255dfec8ffaa1926c97ec49cbec9b3afdeb220c5461d83959ed30acf3bb86e64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100e95760003560e01c8063918648051161008c578063c46647e211610066578063c46647e2146101ad578063cc6a5c9b146101c0578063d024f867146101d3578063ec000108146101e657600080fd5b8063918648051461018057806398de855414610193578063aa02b2b21461019a57600080fd5b806360fb5709116100c857806360fb57091461013b5780637137088914610151578063725bd463146101585780638ff916f81461016d57600080fd5b806232b444146100ee57806301fab8df146101045780631c9caa041461010b575b600080fd5b600e5b6040519081526020015b60405180910390f35b60266100f1565b61011e610119366004610c36565b61020e565b6040516bffffffffffffffffffffffff90911681526020016100fb565b60015b60405161ffff90911681526020016100fb565b60026100f1565b61016061021f565b6040516100fb9190610cc7565b61011e61017b366004610c36565b610283565b61011e61018e366004610c36565b61028e565b601a6100f1565b61011e6101a8366004610c36565b610299565b61013e6101bb366004610c36565b6102a4565b61011e6101ce366004610c36565b6102af565b6101606101e1366004610cfb565b6102ba565b6101f96101f4366004610d7e565b61034c565b60405162ffffff1990911681526020016100fb565b600061021982610357565b92915050565b606061027e604080517e010000000000000000000000000000000000000000000000000000000000006020820152600060228201819052602e8201819052603a8201819052604682015281518082036032018152605290910190915290565b905090565b600061021982610390565b6000610219826103b1565b600061021982610408565b600061021982610429565b60006102198261044a565b604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffff000000000000000000000000000000000000000060a087811b8216602284015286811b8216602e84015285811b8216603a84015284901b1660468201528151808203603201815260529091019091526060905b95945050505050565b60006102198261046b565b60008161036d60025b62ffffff19831690610478565b5061038162ffffff1984166026600c61059c565b63ffffffff1691505b50919050565b60008161039d6002610360565b5061038162ffffff1984166002600c61059c565b6000816103be6002610360565b506103c883610357565b6103d18461044a565b6103da85610408565b6103e386610390565b6103ed9190610e7c565b6103f79190610e7c565b6104019190610e7c565b9392505050565b6000816104156002610360565b5061038162ffffff198416600e600c61059c565b6000816104366002610360565b5061040162ffffff1984166000600261059c565b6000816104576002610360565b5061038162ffffff198416601a600c61059c565b60006102198260026105cc565b600061048483836105e7565b6105955760006104a36104978560d81c90565b64ffffffffff1661060a565b91505060006104b88464ffffffffff1661060a565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e016040516020818303038152906040529050806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60405180910390fd5b5090919050565b60006105a9826020610eac565b6105b4906008610ecf565b60ff166105c28585856106f4565b901c949350505050565b81516000906020840161034364ffffffffff851682846108e6565b60008164ffffffffff166105fb8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff16111561067d576000610629826008610ecf565b60ff1685901c905061063a8161092d565b61ffff16841793508160ff1660101461065557601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610610565b50600f5b60ff8160ff1610156106ee57600061069a826008610ecf565b60ff1685901c90506106ab8161092d565b61ffff16831792508160ff166000146106c657601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610681565b50915091565b60008160ff1660000361070957506000610401565b6107218460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1661073c60ff841685610ef8565b11156107ce5761079b61075d8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166107838660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661095f565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058c9190610cc7565b60208260ff161115610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161058c565b6008820260006108808660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000806108f38385610ef8565b9050604051811115610903575060005b806000036109185762ffffff19915050610401565b5050606092831b9190911790911b1760181b90565b600061093f60048360ff16901c610aef565b60ff1661ffff919091161760081b61095682610aef565b60ff1617919050565b6060600061096c8661060a565b915050600061097a8661060a565b91505060006109888661060a565b91505060006109968661060a565b604080517f54797065644d656d566965772f696e646578202d204f76657272616e2074686560208201527f20766965772e20536c6963652069732061742030780000000000000000000000818301527fffffffffffff000000000000000000000000000000000000000000000000000060d098891b811660558301527f2077697468206c656e6774682030780000000000000000000000000000000000605b830181905297891b8116606a8301527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060708301527f7800000000000000000000000000000000000000000000000000000000000000609083015295881b861660918201526097810196909652951b90921660a684015250507f2e0000000000000000000000000000000000000000000000000000000000000060ac8201528151808203608d01815260ad90910190915295945050505050565b600060f08083179060ff82169003610b0a5750603092915050565b8060ff1660f103610b1e5750603192915050565b8060ff1660f203610b325750603292915050565b8060ff1660f303610b465750603392915050565b8060ff1660f403610b5a5750603492915050565b8060ff1660f503610b6e5750603592915050565b8060ff1660f603610b825750603692915050565b8060ff1660f703610b965750603792915050565b8060ff1660f803610baa5750603892915050565b8060ff1660f903610bbe5750603992915050565b8060ff1660fa03610bd25750606192915050565b8060ff1660fb03610be65750606292915050565b8060ff1660fc03610bfa5750606392915050565b8060ff1660fd03610c0e5750606492915050565b8060ff1660fe03610c225750606592915050565b8060ff1660ff0361038a5750606692915050565b600060208284031215610c4857600080fd5b813562ffffff198116811461040157600080fd5b6000815180845260005b81811015610c8257602081850181015186830182015201610c66565b81811115610c94576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006104016020830184610c5c565b80356bffffffffffffffffffffffff81168114610cf657600080fd5b919050565b60008060008060808587031215610d1157600080fd5b610d1a85610cda565b9350610d2860208601610cda565b9250610d3660408601610cda565b9150610d4460608601610cda565b905092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215610d9057600080fd5b813567ffffffffffffffff80821115610da857600080fd5b818401915084601f830112610dbc57600080fd5b813581811115610dce57610dce610d4f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610e1457610e14610d4f565b81604052828152876020848701011115610e2d57600080fd5b826020860160208301376000928101602001929092525095945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818516808303821115610ea357610ea3610e4d565b01949350505050565b600060ff821660ff841680821015610ec657610ec6610e4d565b90039392505050565b600060ff821660ff84168160ff0481118215151615610ef057610ef0610e4d565b029392505050565b60008219821115610f0b57610f0b610e4d565b50019056fea26469706673582212208f255dfec8ffaa1926c97ec49cbec9b3afdeb220c5461d83959ed30acf3bb86e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n */\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44736:1966:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"44736:1966:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45021:98;42223:2;45021:98;;;160:25:1;;;148:2;133:18;45021:98:0;;;;;;;;45227:102;42326:2;45227:102;;46468:116;;;;;;:::i;:::-;;:::i;:::-;;;708:26:1;696:39;;;678:58;;666:2;651:18;46468:116:0;534:208:1;44818:93:0;41794:1;44818:93;;;921:6:1;909:19;;;891:38;;879:2;864:18;44818:93:0;747:188:1;44917:98:0;42173:1;44917:98;;45607;;;:::i;:::-;;;;;;;:::i;45992:112::-;;;;;;:::i;:::-;;:::i;46590:110::-;;;;;;:::i;:::-;;:::i;45125:96::-;42273:2;45125:96;;46151:112;;;;;;:::i;:::-;;:::i;45831:114::-;;;;;;:::i;:::-;;:::i;46309:110::-;;;;;;:::i;:::-;;:::i;45335:266::-;;;;;;:::i;:::-;;:::i;45711:114::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;3625:79:1;;;3607:98;;3595:2;3580:18;45711:114:0;3461:250:1;46468:116:0;46528:6;46553:24;46571:5;46553:17;:24::i;:::-;46546:31;46468:116;-1:-1:-1;;46468:116:0:o;45607:98::-;45651:12;45682:16;42931:83;;;4590:16:1;42931:83:0;;;4574:102:1;43204:1:0;4777:11:1;;;4770:46;;;4832:12;;;4825:47;;;4888:12;;;4881:47;;;4944:12;;;4937:47;42931:83:0;;;;;;;;;5000:12:1;;;;42931:83:0;;;45607:98;;45682:16;45675:23;;45607:98;:::o;45992:112::-;46050:6;46075:22;46091:5;46075:15;:22::i;46590:110::-;46647:6;46672:21;46687:5;46672:14;:21::i;46151:112::-;46209:6;46234:22;46250:5;46234:15;:22::i;45831:114::-;45890:6;45915:23;45932:5;45915:16;:23::i;46309:110::-;46366:6;46391:21;46406:5;46391:14;:21::i;45335:266::-;42931:83;;;4590:16:1;42931:83:0;;;4574:102:1;4695:66;4798:3;4794:16;;;4790:25;;4777:11;;;4770:46;4850:16;;;4846:25;;4832:12;;;4825:47;4906:16;;;4902:25;;4888:12;;;4881:47;4962:16;;;4958:25;4944:12;;;4937:47;42931:83:0;;;;;;;;;5000:12:1;;;;42931:83:0;;;45495:12;;45526:68;45519:75;45335:266;-1:-1:-1;;;;;45335:266:0:o;45711:114::-;45772:7;45798:20;45812:5;45798:13;:20::i;44319:153::-;44395:6;44379:5;42378:35;37393:10;37386:18;-1:-1:-1;;42378:16:0;;;;:35::i;:::-;-1:-1:-1;44427:37:0::1;-1:-1:-1::0;;44427:15:0;::::1;42326:2;44461;44427:15;:37::i;:::-;44413:52;;;;42423:1;44319:153:::0;;;;:::o;43732:149::-;43806:6;43790:5;42378:35;37393:10;37386:18;;42378:35;-1:-1:-1;43838:35:0::1;-1:-1:-1::0;;43838:15:0;::::1;42173:1;43870:2;43838:15;:35::i;44478:183::-:0;44551:6;44535:5;42378:35;37393:10;37386:18;;42378:35;;44635:19:::1;44648:5;44635:12;:19::i;:::-;44616:16;44626:5;44616:9;:16::i;:::-;44596:17;44607:5;44596:10;:17::i;:::-;44576;44587:5;44576:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;44569:85:::0;44478:183;-1:-1:-1;;;44478:183:0:o;43928:149::-;44002:6;43986:5;42378:35;37393:10;37386:18;;42378:35;-1:-1:-1;44034:35:0::1;-1:-1:-1::0;;44034:15:0;::::1;42223:2;44066;44034:15;:35::i;43549:136::-:0;43624:6;43608:5;42378:35;37393:10;37386:18;;42378:35;-1:-1:-1;43656:21:0::1;-1:-1:-1::0;;43656:15:0;::::1;43672:1;43675;43656:15;:21::i;44123:147::-:0;44196:6;44180:5;42378:35;37393:10;37386:18;;42378:35;-1:-1:-1;44228:34:0::1;-1:-1:-1::0;;44228:15:0;::::1;42273:2;44259;44228:15;:34::i;43371:122::-:0;43432:7;43458:28;:5;37393:10;43458:9;:28::i;10073:578::-;10151:7;10175:26;10182:7;10191:9;10175:6;:26::i;:::-;10170:451;;10220:9;10233:35;10251:15;10258:7;14417:3;14413:17;;14206:268;10251:15;10243:24;;10233:9;:35::i;:::-;10217:51;;;10285:9;10298:29;10316:9;10308:18;;10298:9;:29::i;:::-;10385:186;;5390:31:1;10385:186:0;;;5378:44:1;5441:66;5545:3;5541:16;;;5537:25;;5523:12;;;5516:47;5593:15;5579:12;;;5572:37;5643:16;;;5639:25;5625:12;;;5618:47;10282:45:0;;-1:-1:-1;10341:17:0;;-1:-1:-1;5681:12:1;;10385:186:0;;;;;;;;;;;;10341:244;;10606:3;10599:11;;;;;;;;;;;:::i;:::-;;;;;;;;10170:451;-1:-1:-1;10637:7:0;;10073:578;-1:-1:-1;10073:578:0:o;21121:221::-;21240:14;21318:11;21323:6;21318:2;:11;:::i;:::-;21317:17;;21333:1;21317:17;:::i;:::-;21273:62;;21281:30;21287:7;21296:6;21304;21281:5;:30::i;:::-;21273:62;;;21121:221;-1:-1:-1;;;;21121:221:0:o;13655:359::-;13759:10;;13725:7;;13906:4;13897:14;;13981:26;;;;13897:14;13759:10;13981:5;:26::i;9643:132::-;9717:4;9759:9;9740:28;;:15;9747:7;14417:3;14413:17;;14206:268;9740:15;:28;;;;9643:132;-1:-1:-1;;;9643:132:0:o;5031:667::-;5085:13;;5141:2;5126:258;5149:2;5145:1;:6;;;5126:258;;;5169:11;5196:5;:1;5200;5196:5;:::i;:::-;5189:13;;:2;:13;;5169:34;;5226:14;5234:5;5226:7;:14::i;:::-;5217:23;;;;;;5258:1;:7;;5263:2;5258:7;5254:58;;5295:2;5285:12;;;;;5254:58;-1:-1:-1;5353:6:0;;5126:258;;;-1:-1:-1;5447:2:0;5432:260;5455:3;5451:1;:7;;;5432:260;;;5476:11;5503:5;:1;5507;5503:5;:::i;:::-;5496:13;;:2;:13;;5476:34;;5534:14;5542:5;5534:7;:14::i;:::-;5524:24;;;;;;5566:1;:6;;5571:1;5566:6;5562:58;;5603:2;5592:13;;;;;5562:58;-1:-1:-1;5661:6:0;;5432:260;;;;5031:667;;;:::o;20004:771::-;20119:14;20149:6;:11;;20159:1;20149:11;20145:59;;-1:-1:-1;20191:1:0;20176:17;;20145:59;20235:12;20239:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20235:12;20217:30;;:15;;;;:6;:15;:::i;:::-;:30;20213:137;;;20270:68;20286:12;20290:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20286:12;20270:68;;20300:12;20304:7;16492:2;16488:16;2670:26;16484:28;;16246:282;20300:12;20270:68;;20314:6;20330;20322:15;;20270;:68::i;:::-;20263:76;;;;;;;;;;;:::i;20213:137::-;20377:2;20367:6;:12;;;;20359:83;;;;;;;6706:2:1;20359:83:0;;;6688:21:1;6745:2;6725:18;;;6718:30;6784:34;6764:18;;;6757:62;6855:28;6835:18;;;6828:56;6901:19;;20359:83:0;6504:422:1;20359:83:0;20523:1;20514:10;;20453:15;20559:12;20563:7;15386:3;15382:17;2670:26;15378:29;;15059:364;20559:12;20544:27;;;-1:-1:-1;20581:13:0;7488:66;7458:12;;;7437:131;20733:17;;;;20727:24;20723:36;;;-1:-1:-1;;;;;20004:771:0:o;12796:462::-;12907:15;;12949:11;12956:4;12949;:11;:::i;:::-;12934:26;;13075:4;13069:11;13063:4;13060:21;13057:66;;;-1:-1:-1;13108:1:0;13057:66;13146:4;13154:1;13146:9;13142:51;;-1:-1:-1;;13171:11:0;;;;;13142:51;-1:-1:-1;;12065:2:0;12061:27;;;12135:17;;;;12127:26;;;12199:17;12195:2;12191:26;;12796:462::o;4508:199::-;4558:14;4595:18;4611:1;4605:2;:7;;;;4595:9;:18::i;:::-;4584:29;;4637:13;;;;;;4649:1;4637:13;4671;4681:2;4671:9;:13::i;:::-;4660:24;;;;4508:199;-1:-1:-1;4508:199:0:o;18761:741::-;18907:17;18939:9;18952:15;18962:4;18952:9;:15::i;:::-;18936:31;;;18980:9;18993:15;19003:4;18993:9;:15::i;:::-;18977:31;;;19021:9;19034:17;19044:6;19034:9;:17::i;:::-;19018:33;;;19064:9;19077:17;19087:6;19077:9;:17::i;:::-;19130:355;;;7772:34:1;19130:355:0;;;7760:47:1;7837:23;7823:12;;;7816:45;7880:66;7984:3;7980:16;;;7976:25;;7962:12;;;7955:47;8021:17;8054:12;;;8047:24;;;8105:16;;;8101:25;;8087:12;;;8080:47;8157:34;8143:12;;;8136:56;8223:3;8208:13;;;8201:26;8262:16;;;8258:25;;8243:13;;;8236:48;8300:13;;;8293:25;;;;8353:16;;8349:25;;;8334:13;;;8327:48;-1:-1:-1;;7008:3:1;8421:13;;;6996:16;19130:355:0;;;;;;;;;7028:11:1;;;;19130:355:0;;;;;-1:-1:-1;;;;;18761:741:0:o;2943:1393::-;2995:10;3161:4;3156:9;;;;3207:15;;;;;3203:57;;-1:-1:-1;3245:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3203:57::-;3278:7;:15;;3289:4;3278:15;3274:57;;-1:-1:-1;3316:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3274:57::-;3349:7;:15;;3360:4;3349:15;3345:57;;-1:-1:-1;3387:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3345:57::-;3420:7;:15;;3431:4;3420:15;3416:57;;-1:-1:-1;3458:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;2943:1393;-1:-1:-1;;2943:1393:0:o;196:333:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;363:9;350:23;-1:-1:-1;;406:5:1;402:78;395:5;392:89;382:117;;495:1;492;485:12;940:530;981:3;1019:5;1013:12;1046:6;1041:3;1034:19;1071:1;1081:162;1095:6;1092:1;1089:13;1081:162;;;1157:4;1213:13;;;1209:22;;1203:29;1185:11;;;1181:20;;1174:59;1110:12;1081:162;;;1261:6;1258:1;1255:13;1252:87;;;1327:1;1320:4;1311:6;1306:3;1302:16;1298:27;1291:38;1252:87;-1:-1:-1;1384:2:1;1372:15;1389:66;1368:88;1359:98;;;;1459:4;1355:109;;940:530;-1:-1:-1;;940:530:1:o;1475:217::-;1622:2;1611:9;1604:21;1585:4;1642:44;1682:2;1671:9;1667:18;1659:6;1642:44;:::i;1697:179::-;1764:20;;1824:26;1813:38;;1803:49;;1793:77;;1866:1;1863;1856:12;1793:77;1697:179;;;:::o;1881:401::-;1963:6;1971;1979;1987;2040:3;2028:9;2019:7;2015:23;2011:33;2008:53;;;2057:1;2054;2047:12;2008:53;2080:28;2098:9;2080:28;:::i;:::-;2070:38;;2127:37;2160:2;2149:9;2145:18;2127:37;:::i;:::-;2117:47;;2183:37;2216:2;2205:9;2201:18;2183:37;:::i;:::-;2173:47;;2239:37;2272:2;2261:9;2257:18;2239:37;:::i;:::-;2229:47;;1881:401;;;;;;;:::o;2287:184::-;2339:77;2336:1;2329:88;2436:4;2433:1;2426:15;2460:4;2457:1;2450:15;2476:980;2544:6;2597:2;2585:9;2576:7;2572:23;2568:32;2565:52;;;2613:1;2610;2603:12;2565:52;2653:9;2640:23;2682:18;2723:2;2715:6;2712:14;2709:34;;;2739:1;2736;2729:12;2709:34;2777:6;2766:9;2762:22;2752:32;;2822:7;2815:4;2811:2;2807:13;2803:27;2793:55;;2844:1;2841;2834:12;2793:55;2880:2;2867:16;2902:2;2898;2895:10;2892:36;;;2908:18;;:::i;:::-;3042:2;3036:9;3104:4;3096:13;;2947:66;3092:22;;;3116:2;3088:31;3084:40;3072:53;;;3140:18;;;3160:22;;;3137:46;3134:72;;;3186:18;;:::i;:::-;3226:10;3222:2;3215:22;3261:2;3253:6;3246:18;3301:7;3296:2;3291;3287;3283:11;3279:20;3276:33;3273:53;;;3322:1;3319;3312:12;3273:53;3378:2;3373;3369;3365:11;3360:2;3352:6;3348:15;3335:46;3423:1;3401:15;;;3418:2;3397:24;3390:35;;;;-1:-1:-1;3405:6:1;2476:980;-1:-1:-1;;;;;2476:980:1:o;3905:184::-;3957:77;3954:1;3947:88;4054:4;4051:1;4044:15;4078:4;4075:1;4068:15;4094:244;4133:3;4161:26;4214:2;4211:1;4207:10;4244:2;4241:1;4237:10;4275:3;4271:2;4267:12;4262:3;4259:21;4256:47;;;4283:18;;:::i;:::-;4319:13;;4094:244;-1:-1:-1;;;;4094:244:1:o;5928:195::-;5966:4;6003;6000:1;5996:12;6035:4;6032:1;6028:12;6060:3;6055;6052:12;6049:38;;;6067:18;;:::i;:::-;6104:13;;;5928:195;-1:-1:-1;;;5928:195:1:o;6128:238::-;6166:7;6206:4;6203:1;6199:12;6238:4;6235:1;6231:12;6298:3;6292:4;6288:14;6283:3;6280:23;6273:3;6266:11;6259:19;6255:49;6252:75;;;6307:18;;:::i;:::-;6347:13;;6128:238;-1:-1:-1;;;6128:238:1:o;6371:128::-;6411:3;6442:1;6438:6;6435:1;6432:13;6429:39;;;6448:18;;:::i;:::-;-1:-1:-1;6484:9:1;;6371:128::o","abiDefinition":[{"inputs":[],"name":"emptyTips","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint96","name":"_updaterTip","type":"uint96"},{"internalType":"uint96","name":"_relayerTip","type":"uint96"},{"internalType":"uint96","name":"_proverTip","type":"uint96"},{"internalType":"uint96","name":"_processorTip","type":"uint96"}],"name":"formatTips","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetProcessor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetProver","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetRelayer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"offsetUpdater","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"processorTip","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"proverTip","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"relayerTip","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"tipsVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"tipsVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_tips","type":"bytes"}],"name":"tipsView","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"totalTips","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes29","name":"_tips","type":"bytes29"}],"name":"updaterTip","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"pure","type":"function"}],"userDoc":{"kind":"user","methods":{"processorTip(bytes29)":{"notice":"Returns processorTip field"},"proverTip(bytes29)":{"notice":"Returns proverTip field"},"relayerTip(bytes29)":{"notice":"Returns relayerTip field"},"updaterTip(bytes29)":{"notice":"Returns updaterTip field"}},"notice":"exposes tips methods for testing against golang","version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"emptyTips\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"_updaterTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_relayerTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_proverTip\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_processorTip\",\"type\":\"uint96\"}],\"name\":\"formatTips\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetProcessor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetProver\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetRelayer\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"offsetUpdater\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"processorTip\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"proverTip\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"relayerTip\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tipsVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"tipsVersion\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"}],\"name\":\"tipsView\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"totalTips\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes29\",\"name\":\"_tips\",\"type\":\"bytes29\"}],\"name\":\"updaterTip\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"processorTip(bytes29)\":{\"notice\":\"Returns processorTip field\"},\"proverTip(bytes29)\":{\"notice\":\"Returns proverTip field\"},\"relayerTip(bytes29)\":{\"notice\":\"Returns relayerTip field\"},\"updaterTip(bytes29)\":{\"notice\":\"Returns updaterTip field\"}},\"notice\":\"exposes tips methods for testing against golang\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"TipsHarness\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x1e84f57bd0ef3366dae1ca132da5b135ccbdc498c09418f92319847884b59028\",\"urls\":[\"bzz-raw://14fc1754929893ac24d22163e79f0bfded428449ed815cd8d06443c37fa211c9\",\"dweb:/ipfs/QmUBZuHuxiAnpJ6G5tbBvTjsCP9yLsQ9QPbTgpARk2FbE4\"]}},\"version\":1}"},"hashes":{"emptyTips()":"725bd463","formatTips(uint96,uint96,uint96,uint96)":"d024f867","offsetProcessor()":"01fab8df","offsetProver()":"98de8554","offsetRelayer()":"0032b444","offsetUpdater()":"71370889","processorTip(bytes29)":"1c9caa04","proverTip(bytes29)":"cc6a5c9b","relayerTip(bytes29)":"aa02b2b2","tipsVersion()":"60fb5709","tipsVersion(bytes29)":"c46647e2","tipsView(bytes)":"ec000108","totalTips(bytes29)":"91864805","updaterTip(bytes29)":"8ff916f8"}},"solidity/TipsHarness.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207a4a829a4ff4787148001272e92eb978a36314f1e5fb49597cce4efaf4118a2064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207a4a829a4ff4787148001272e92eb978a36314f1e5fb49597cce4efaf4118a2064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n */\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32274:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32274:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32274:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x1e84f57bd0ef3366dae1ca132da5b135ccbdc498c09418f92319847884b59028\",\"urls\":[\"bzz-raw://14fc1754929893ac24d22163e79f0bfded428449ed815cd8d06443c37fa211c9\",\"dweb:/ipfs/QmUBZuHuxiAnpJ6G5tbBvTjsCP9yLsQ9QPbTgpARk2FbE4\"]}},\"version\":1}"},"hashes":{}},"solidity/TipsHarness.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122078c50a2fa8be8f96b424fd97322fe02bd9fbb184e917c2c74eaea55a9edfa96764736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea264697066735822122078c50a2fa8be8f96b424fd97322fe02bd9fbb184e917c2c74eaea55a9edfa96764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\n// \n/**\n * @notice exposes tips methods for testing against golang\n */\ncontract TipsHarness {\n using Tips for bytes;\n using Tips for bytes29;\n\n function tipsVersion() public pure returns (uint16) {\n return Tips.TIPS_VERSION;\n }\n\n function offsetUpdater() public pure returns (uint256) {\n return Tips.OFFSET_UPDATER;\n }\n\n function offsetRelayer() public pure returns (uint256) {\n return Tips.OFFSET_RELAYER;\n }\n\n function offsetProver() public pure returns (uint256) {\n return Tips.OFFSET_PROVER;\n }\n\n function offsetProcessor() public pure returns (uint256) {\n return Tips.OFFSET_PROCESSOR;\n }\n\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) public pure returns (bytes memory) {\n return Tips.formatTips(_updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n function emptyTips() external pure returns (bytes memory) {\n return Tips.emptyTips();\n }\n\n function tipsView(bytes memory _tips) external pure returns (bytes29) {\n return Tips.tipsView(_tips);\n }\n\n function tipsVersion(bytes29 _tips) external pure returns (uint16) {\n return Tips.tipsVersion(_tips);\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.updaterTip(_tips);\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.relayerTip(_tips);\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.proverTip(_tips);\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) external pure returns (uint96) {\n return Tips.processorTip(_tips);\n }\n\n function totalTips(bytes29 _tips) external pure returns (uint96) {\n return Tips.totalTips(_tips);\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"26:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;26:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"26:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2539:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2539:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/TipsHarness.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/TipsHarness.sol\":{\"keccak256\":\"0x1e84f57bd0ef3366dae1ca132da5b135ccbdc498c09418f92319847884b59028\",\"urls\":[\"bzz-raw://14fc1754929893ac24d22163e79f0bfded428449ed815cd8d06443c37fa211c9\",\"dweb:/ipfs/QmUBZuHuxiAnpJ6G5tbBvTjsCP9yLsQ9QPbTgpARk2FbE4\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}}} \ No newline at end of file diff --git a/core/contracts/updatermanager/updatemanager.abigen.go b/core/contracts/updatermanager/updatemanager.abigen.go index 2c422524ea..248f60dbe7 100644 --- a/core/contracts/updatermanager/updatemanager.abigen.go +++ b/core/contracts/updatermanager/updatemanager.abigen.go @@ -28,10 +28,312 @@ var ( _ = event.NewSubscription ) +// AbstractGuardRegistryMetaData contains all meta data concerning the AbstractGuardRegistry contract. +var AbstractGuardRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractGuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractGuardRegistryMetaData.ABI instead. +var AbstractGuardRegistryABI = AbstractGuardRegistryMetaData.ABI + +// AbstractGuardRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractGuardRegistry struct { + AbstractGuardRegistryCaller // Read-only binding to the contract + AbstractGuardRegistryTransactor // Write-only binding to the contract + AbstractGuardRegistryFilterer // Log filterer for contract events +} + +// AbstractGuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractGuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractGuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractGuardRegistrySession struct { + Contract *AbstractGuardRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractGuardRegistryCallerSession struct { + Contract *AbstractGuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractGuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractGuardRegistryTransactorSession struct { + Contract *AbstractGuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractGuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractGuardRegistryRaw struct { + Contract *AbstractGuardRegistry // Generic contract binding to access the raw methods on +} + +// AbstractGuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractGuardRegistryCallerRaw struct { + Contract *AbstractGuardRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractGuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractGuardRegistryTransactorRaw struct { + Contract *AbstractGuardRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractGuardRegistry creates a new instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistry(address common.Address, backend bind.ContractBackend) (*AbstractGuardRegistry, error) { + contract, err := bindAbstractGuardRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractGuardRegistry{AbstractGuardRegistryCaller: AbstractGuardRegistryCaller{contract: contract}, AbstractGuardRegistryTransactor: AbstractGuardRegistryTransactor{contract: contract}, AbstractGuardRegistryFilterer: AbstractGuardRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractGuardRegistryCaller creates a new read-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractGuardRegistryCaller, error) { + contract, err := bindAbstractGuardRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryCaller{contract: contract}, nil +} + +// NewAbstractGuardRegistryTransactor creates a new write-only instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractGuardRegistryTransactor, error) { + contract, err := bindAbstractGuardRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryTransactor{contract: contract}, nil +} + +// NewAbstractGuardRegistryFilterer creates a new log filterer instance of AbstractGuardRegistry, bound to a specific deployed contract. +func NewAbstractGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractGuardRegistryFilterer, error) { + contract, err := bindAbstractGuardRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractGuardRegistryFilterer{contract: contract}, nil +} + +// bindAbstractGuardRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractGuardRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.AbstractGuardRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractGuardRegistry *AbstractGuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractGuardRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractGuardRegistry *AbstractGuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractGuardRegistry.Contract.contract.Transact(opts, method, params...) +} + +// AbstractNotaryRegistryMetaData contains all meta data concerning the AbstractNotaryRegistry contract. +var AbstractNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[]", +} + +// AbstractNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use AbstractNotaryRegistryMetaData.ABI instead. +var AbstractNotaryRegistryABI = AbstractNotaryRegistryMetaData.ABI + +// AbstractNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type AbstractNotaryRegistry struct { + AbstractNotaryRegistryCaller // Read-only binding to the contract + AbstractNotaryRegistryTransactor // Write-only binding to the contract + AbstractNotaryRegistryFilterer // Log filterer for contract events +} + +// AbstractNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type AbstractNotaryRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// AbstractNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type AbstractNotaryRegistrySession struct { + Contract *AbstractNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type AbstractNotaryRegistryCallerSession struct { + Contract *AbstractNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// AbstractNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type AbstractNotaryRegistryTransactorSession struct { + Contract *AbstractNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// AbstractNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type AbstractNotaryRegistryRaw struct { + Contract *AbstractNotaryRegistry // Generic contract binding to access the raw methods on +} + +// AbstractNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryCallerRaw struct { + Contract *AbstractNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on +} + +// AbstractNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type AbstractNotaryRegistryTransactorRaw struct { + Contract *AbstractNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewAbstractNotaryRegistry creates a new instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistry(address common.Address, backend bind.ContractBackend) (*AbstractNotaryRegistry, error) { + contract, err := bindAbstractNotaryRegistry(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistry{AbstractNotaryRegistryCaller: AbstractNotaryRegistryCaller{contract: contract}, AbstractNotaryRegistryTransactor: AbstractNotaryRegistryTransactor{contract: contract}, AbstractNotaryRegistryFilterer: AbstractNotaryRegistryFilterer{contract: contract}}, nil +} + +// NewAbstractNotaryRegistryCaller creates a new read-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*AbstractNotaryRegistryCaller, error) { + contract, err := bindAbstractNotaryRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryCaller{contract: contract}, nil +} + +// NewAbstractNotaryRegistryTransactor creates a new write-only instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*AbstractNotaryRegistryTransactor, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryTransactor{contract: contract}, nil +} + +// NewAbstractNotaryRegistryFilterer creates a new log filterer instance of AbstractNotaryRegistry, bound to a specific deployed contract. +func NewAbstractNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*AbstractNotaryRegistryFilterer, error) { + contract, err := bindAbstractNotaryRegistry(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &AbstractNotaryRegistryFilterer{contract: contract}, nil +} + +// bindAbstractNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindAbstractNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(AbstractNotaryRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.AbstractNotaryRegistryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _AbstractNotaryRegistry.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_AbstractNotaryRegistry *AbstractNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _AbstractNotaryRegistry.Contract.contract.Transact(opts, method, params...) +} + // AddressMetaData contains all meta data concerning the Address contract. var AddressMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f2b2b5dedff2c43ed96b31a6c55c27c393332adc0f7c50d60ace08bba94afb0364736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220173016a61f21743599903dd0d6ddd5b3dad05e450eb61cbfa1bef7e9cdd1125464736f6c634300080d0033", } // AddressABI is the input ABI used to generate the binding from. @@ -204,7 +506,7 @@ func (_Address *AddressTransactorRaw) Transact(opts *bind.TransactOpts, method s // AddressUpgradeableMetaData contains all meta data concerning the AddressUpgradeable contract. var AddressUpgradeableMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220efddb409a34a8de640a795f00749b7b1f9a7882c1f54721830599fbabcc1460464736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209038b5275e330d7536c3011fb042d43a4368babfc61b637ed01282db0eca282064736f6c634300080d0033", } // AddressUpgradeableABI is the input ABI used to generate the binding from. @@ -377,7 +679,7 @@ func (_AddressUpgradeable *AddressUpgradeableTransactorRaw) Transact(opts *bind. // AttestationMetaData contains all meta data concerning the Attestation contract. var AttestationMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202b98152b11399d8db72cf434b62ace04bacd73ccb14ac7e7f684d00b38e6a15e64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e6638e47bbfe98a03f10367fbd38f861cb726bb09d0bdf010a2d30ed59e4606164736f6c634300080d0033", } // AttestationABI is the input ABI used to generate the binding from. @@ -550,7 +852,7 @@ func (_Attestation *AttestationTransactorRaw) Transact(opts *bind.TransactOpts, // AuthMetaData contains all meta data concerning the Auth contract. var AuthMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202b29159cd74b901c4dfcb0d00f8df2caaf365677497165a08f18e9108bb0467764736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220faf9cb1a2958413aaa5f5fe79b9603a2e97dd08c57fc9629a8493be25225d5b864736f6c634300080d0033", } // AuthABI is the input ABI used to generate the binding from. @@ -720,157 +1022,6 @@ func (_Auth *AuthTransactorRaw) Transact(opts *bind.TransactOpts, method string, return _Auth.Contract.contract.Transact(opts, method, params...) } -// AuthManagerMetaData contains all meta data concerning the AuthManager contract. -var AuthManagerMetaData = &bind.MetaData{ - ABI: "[]", -} - -// AuthManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use AuthManagerMetaData.ABI instead. -var AuthManagerABI = AuthManagerMetaData.ABI - -// AuthManager is an auto generated Go binding around an Ethereum contract. -type AuthManager struct { - AuthManagerCaller // Read-only binding to the contract - AuthManagerTransactor // Write-only binding to the contract - AuthManagerFilterer // Log filterer for contract events -} - -// AuthManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type AuthManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type AuthManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type AuthManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} - -// AuthManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type AuthManagerSession struct { - Contract *AuthManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type AuthManagerCallerSession struct { - Contract *AuthManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} - -// AuthManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type AuthManagerTransactorSession struct { - Contract *AuthManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} - -// AuthManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type AuthManagerRaw struct { - Contract *AuthManager // Generic contract binding to access the raw methods on -} - -// AuthManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type AuthManagerCallerRaw struct { - Contract *AuthManagerCaller // Generic read-only contract binding to access the raw methods on -} - -// AuthManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type AuthManagerTransactorRaw struct { - Contract *AuthManagerTransactor // Generic write-only contract binding to access the raw methods on -} - -// NewAuthManager creates a new instance of AuthManager, bound to a specific deployed contract. -func NewAuthManager(address common.Address, backend bind.ContractBackend) (*AuthManager, error) { - contract, err := bindAuthManager(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &AuthManager{AuthManagerCaller: AuthManagerCaller{contract: contract}, AuthManagerTransactor: AuthManagerTransactor{contract: contract}, AuthManagerFilterer: AuthManagerFilterer{contract: contract}}, nil -} - -// NewAuthManagerCaller creates a new read-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerCaller(address common.Address, caller bind.ContractCaller) (*AuthManagerCaller, error) { - contract, err := bindAuthManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &AuthManagerCaller{contract: contract}, nil -} - -// NewAuthManagerTransactor creates a new write-only instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*AuthManagerTransactor, error) { - contract, err := bindAuthManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &AuthManagerTransactor{contract: contract}, nil -} - -// NewAuthManagerFilterer creates a new log filterer instance of AuthManager, bound to a specific deployed contract. -func NewAuthManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*AuthManagerFilterer, error) { - contract, err := bindAuthManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &AuthManagerFilterer{contract: contract}, nil -} - -// bindAuthManager binds a generic wrapper to an already deployed contract. -func bindAuthManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(AuthManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.AuthManagerCaller.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.AuthManagerTransactor.contract.Transact(opts, method, params...) -} - -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_AuthManager *AuthManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _AuthManager.Contract.contract.Call(opts, result, method, params...) -} - -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_AuthManager *AuthManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transfer(opts) -} - -// Transact invokes the (paid) contract method with params as input values. -func (_AuthManager *AuthManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _AuthManager.Contract.contract.Transact(opts, method, params...) -} - // ContextMetaData contains all meta data concerning the Context contract. var ContextMetaData = &bind.MetaData{ ABI: "[]", @@ -1307,23 +1458,32 @@ func (_ContextUpgradeable *ContextUpgradeableFilterer) ParseInitialized(log type return event, nil } -// ECDSAMetaData contains all meta data concerning the ECDSA contract. -var ECDSAMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207aa88a93de95559c8a6d7dd8d1fbfc1e6c5dfe1cb45b9417d5276f32f5f0829a64736f6c634300080d0033", -} +// DomainNotaryRegistryMetaData contains all meta data concerning the DomainNotaryRegistry contract. +var DomainNotaryRegistryMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_trackedDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "9817e315": "allNotaries()", + "c07dc7f5": "getNotary(uint256)", + "8e62e9ef": "notariesAmount()", + }, + Bin: "0x60a060405234801561001057600080fd5b506040516102e73803806102e783398101604081905261002f9161003d565b63ffffffff1660805261006a565b60006020828403121561004f57600080fd5b815163ffffffff8116811461006357600080fd5b9392505050565b608051610265610082600039600050506102656000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207ef2ba07bd558db2e2e06e92ae876a511cef227a7494199035e127c36887c73864736f6c634300080d0033", +} -// ECDSAABI is the input ABI used to generate the binding from. -// Deprecated: Use ECDSAMetaData.ABI instead. -var ECDSAABI = ECDSAMetaData.ABI +// DomainNotaryRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use DomainNotaryRegistryMetaData.ABI instead. +var DomainNotaryRegistryABI = DomainNotaryRegistryMetaData.ABI -// ECDSABin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use ECDSAMetaData.Bin instead. -var ECDSABin = ECDSAMetaData.Bin +// Deprecated: Use DomainNotaryRegistryMetaData.Sigs instead. +// DomainNotaryRegistryFuncSigs maps the 4-byte function signature to its string representation. +var DomainNotaryRegistryFuncSigs = DomainNotaryRegistryMetaData.Sigs -// DeployECDSA deploys a new Ethereum contract, binding an instance of ECDSA to it. -func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ECDSA, error) { - parsed, err := ECDSAMetaData.GetAbi() +// DomainNotaryRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use DomainNotaryRegistryMetaData.Bin instead. +var DomainNotaryRegistryBin = DomainNotaryRegistryMetaData.Bin + +// DeployDomainNotaryRegistry deploys a new Ethereum contract, binding an instance of DomainNotaryRegistry to it. +func DeployDomainNotaryRegistry(auth *bind.TransactOpts, backend bind.ContractBackend, _trackedDomain uint32) (common.Address, *types.Transaction, *DomainNotaryRegistry, error) { + parsed, err := DomainNotaryRegistryMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1331,111 +1491,111 @@ func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common. return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ECDSABin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(DomainNotaryRegistryBin), backend, _trackedDomain) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil + return address, tx, &DomainNotaryRegistry{DomainNotaryRegistryCaller: DomainNotaryRegistryCaller{contract: contract}, DomainNotaryRegistryTransactor: DomainNotaryRegistryTransactor{contract: contract}, DomainNotaryRegistryFilterer: DomainNotaryRegistryFilterer{contract: contract}}, nil } -// ECDSA is an auto generated Go binding around an Ethereum contract. -type ECDSA struct { - ECDSACaller // Read-only binding to the contract - ECDSATransactor // Write-only binding to the contract - ECDSAFilterer // Log filterer for contract events +// DomainNotaryRegistry is an auto generated Go binding around an Ethereum contract. +type DomainNotaryRegistry struct { + DomainNotaryRegistryCaller // Read-only binding to the contract + DomainNotaryRegistryTransactor // Write-only binding to the contract + DomainNotaryRegistryFilterer // Log filterer for contract events } -// ECDSACaller is an auto generated read-only Go binding around an Ethereum contract. -type ECDSACaller struct { +// DomainNotaryRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type DomainNotaryRegistryCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSATransactor is an auto generated write-only Go binding around an Ethereum contract. -type ECDSATransactor struct { +// DomainNotaryRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type DomainNotaryRegistryTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSAFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ECDSAFilterer struct { +// DomainNotaryRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type DomainNotaryRegistryFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ECDSASession is an auto generated Go binding around an Ethereum contract, +// DomainNotaryRegistrySession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type ECDSASession struct { - Contract *ECDSA // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type DomainNotaryRegistrySession struct { + Contract *DomainNotaryRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ECDSACallerSession is an auto generated read-only Go binding around an Ethereum contract, +// DomainNotaryRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type ECDSACallerSession struct { - Contract *ECDSACaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type DomainNotaryRegistryCallerSession struct { + Contract *DomainNotaryRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// ECDSATransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// DomainNotaryRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type ECDSATransactorSession struct { - Contract *ECDSATransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type DomainNotaryRegistryTransactorSession struct { + Contract *DomainNotaryRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// ECDSARaw is an auto generated low-level Go binding around an Ethereum contract. -type ECDSARaw struct { - Contract *ECDSA // Generic contract binding to access the raw methods on +// DomainNotaryRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type DomainNotaryRegistryRaw struct { + Contract *DomainNotaryRegistry // Generic contract binding to access the raw methods on } -// ECDSACallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ECDSACallerRaw struct { - Contract *ECDSACaller // Generic read-only contract binding to access the raw methods on +// DomainNotaryRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type DomainNotaryRegistryCallerRaw struct { + Contract *DomainNotaryRegistryCaller // Generic read-only contract binding to access the raw methods on } -// ECDSATransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ECDSATransactorRaw struct { - Contract *ECDSATransactor // Generic write-only contract binding to access the raw methods on +// DomainNotaryRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type DomainNotaryRegistryTransactorRaw struct { + Contract *DomainNotaryRegistryTransactor // Generic write-only contract binding to access the raw methods on } -// NewECDSA creates a new instance of ECDSA, bound to a specific deployed contract. -func NewECDSA(address common.Address, backend bind.ContractBackend) (*ECDSA, error) { - contract, err := bindECDSA(address, backend, backend, backend) +// NewDomainNotaryRegistry creates a new instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistry(address common.Address, backend bind.ContractBackend) (*DomainNotaryRegistry, error) { + contract, err := bindDomainNotaryRegistry(address, backend, backend, backend) if err != nil { return nil, err } - return &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil + return &DomainNotaryRegistry{DomainNotaryRegistryCaller: DomainNotaryRegistryCaller{contract: contract}, DomainNotaryRegistryTransactor: DomainNotaryRegistryTransactor{contract: contract}, DomainNotaryRegistryFilterer: DomainNotaryRegistryFilterer{contract: contract}}, nil } -// NewECDSACaller creates a new read-only instance of ECDSA, bound to a specific deployed contract. -func NewECDSACaller(address common.Address, caller bind.ContractCaller) (*ECDSACaller, error) { - contract, err := bindECDSA(address, caller, nil, nil) +// NewDomainNotaryRegistryCaller creates a new read-only instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryCaller(address common.Address, caller bind.ContractCaller) (*DomainNotaryRegistryCaller, error) { + contract, err := bindDomainNotaryRegistry(address, caller, nil, nil) if err != nil { return nil, err } - return &ECDSACaller{contract: contract}, nil + return &DomainNotaryRegistryCaller{contract: contract}, nil } -// NewECDSATransactor creates a new write-only instance of ECDSA, bound to a specific deployed contract. -func NewECDSATransactor(address common.Address, transactor bind.ContractTransactor) (*ECDSATransactor, error) { - contract, err := bindECDSA(address, nil, transactor, nil) +// NewDomainNotaryRegistryTransactor creates a new write-only instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*DomainNotaryRegistryTransactor, error) { + contract, err := bindDomainNotaryRegistry(address, nil, transactor, nil) if err != nil { return nil, err } - return &ECDSATransactor{contract: contract}, nil + return &DomainNotaryRegistryTransactor{contract: contract}, nil } -// NewECDSAFilterer creates a new log filterer instance of ECDSA, bound to a specific deployed contract. -func NewECDSAFilterer(address common.Address, filterer bind.ContractFilterer) (*ECDSAFilterer, error) { - contract, err := bindECDSA(address, nil, nil, filterer) +// NewDomainNotaryRegistryFilterer creates a new log filterer instance of DomainNotaryRegistry, bound to a specific deployed contract. +func NewDomainNotaryRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*DomainNotaryRegistryFilterer, error) { + contract, err := bindDomainNotaryRegistry(address, nil, nil, filterer) if err != nil { return nil, err } - return &ECDSAFilterer{contract: contract}, nil + return &DomainNotaryRegistryFilterer{contract: contract}, nil } -// bindECDSA binds a generic wrapper to an already deployed contract. -func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ECDSAABI)) +// bindDomainNotaryRegistry binds a generic wrapper to an already deployed contract. +func bindDomainNotaryRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(DomainNotaryRegistryABI)) if err != nil { return nil, err } @@ -1446,258 +1606,418 @@ func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bi // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ECDSA *ECDSARaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ECDSA.Contract.ECDSACaller.contract.Call(opts, result, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ECDSA *ECDSARaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ECDSA.Contract.ECDSATransactor.contract.Transfer(opts) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ECDSA *ECDSARaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ECDSA.Contract.ECDSATransactor.contract.Transact(opts, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.DomainNotaryRegistryTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_ECDSA *ECDSACallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ECDSA.Contract.contract.Call(opts, result, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _DomainNotaryRegistry.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_ECDSA *ECDSATransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ECDSA.Contract.contract.Transfer(opts) +func (_DomainNotaryRegistry *DomainNotaryRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ECDSA.Contract.contract.Transact(opts, method, params...) +func (_DomainNotaryRegistry *DomainNotaryRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _DomainNotaryRegistry.Contract.contract.Transact(opts, method, params...) } -// HeaderMetaData contains all meta data concerning the Header contract. -var HeaderMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220927355e562dbb5a47568edd04452b2df5ed7678deae00c86b947df6ee4c9359764736f6c634300080d0033", +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) AllNotaries(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "allNotaries") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + } -// HeaderABI is the input ABI used to generate the binding from. -// Deprecated: Use HeaderMetaData.ABI instead. -var HeaderABI = HeaderMetaData.ABI +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) AllNotaries() ([]common.Address, error) { + return _DomainNotaryRegistry.Contract.AllNotaries(&_DomainNotaryRegistry.CallOpts) +} -// HeaderBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HeaderMetaData.Bin instead. -var HeaderBin = HeaderMetaData.Bin +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) AllNotaries() ([]common.Address, error) { + return _DomainNotaryRegistry.Contract.AllNotaries(&_DomainNotaryRegistry.CallOpts) +} -// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. -func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { - parsed, err := HeaderMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "getNotary", _index) - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) if err != nil { - return common.Address{}, nil, nil, err + return *new(common.Address), err } - return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil -} -// Header is an auto generated Go binding around an Ethereum contract. -type Header struct { - HeaderCaller // Read-only binding to the contract - HeaderTransactor // Write-only binding to the contract - HeaderFilterer // Log filterer for contract events -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err -// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. -type HeaderCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HeaderTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) GetNotary(_index *big.Int) (common.Address, error) { + return _DomainNotaryRegistry.Contract.GetNotary(&_DomainNotaryRegistry.CallOpts, _index) } -// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HeaderFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) GetNotary(_index *big.Int) (common.Address, error) { + return _DomainNotaryRegistry.Contract.GetNotary(&_DomainNotaryRegistry.CallOpts, _index) } -// HeaderSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type HeaderSession struct { - Contract *Header // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistryCaller) NotariesAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _DomainNotaryRegistry.contract.Call(opts, &out, "notariesAmount") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type HeaderCallerSession struct { - Contract *HeaderCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistrySession) NotariesAmount() (*big.Int, error) { + return _DomainNotaryRegistry.Contract.NotariesAmount(&_DomainNotaryRegistry.CallOpts) } -// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type HeaderTransactorSession struct { - Contract *HeaderTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_DomainNotaryRegistry *DomainNotaryRegistryCallerSession) NotariesAmount() (*big.Int, error) { + return _DomainNotaryRegistry.Contract.NotariesAmount(&_DomainNotaryRegistry.CallOpts) } -// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. -type HeaderRaw struct { - Contract *Header // Generic contract binding to access the raw methods on +// DomainNotaryRegistryDomainNotaryAddedIterator is returned from FilterDomainNotaryAdded and is used to iterate over the raw logs and unpacked data for DomainNotaryAdded events raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryAddedIterator struct { + Event *DomainNotaryRegistryDomainNotaryAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HeaderCallerRaw struct { - Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HeaderTransactorRaw struct { - Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Error() error { + return it.fail } -// NewHeader creates a new instance of Header, bound to a specific deployed contract. -func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { - contract, err := bindHeader(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DomainNotaryRegistryDomainNotaryAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. -func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { - contract, err := bindHeader(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &HeaderCaller{contract: contract}, nil +// DomainNotaryRegistryDomainNotaryAdded represents a DomainNotaryAdded event raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryAdded struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. -func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { - contract, err := bindHeader(address, nil, transactor, nil) +// FilterDomainNotaryAdded is a free log retrieval operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) FilterDomainNotaryAdded(opts *bind.FilterOpts) (*DomainNotaryRegistryDomainNotaryAddedIterator, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.FilterLogs(opts, "DomainNotaryAdded") if err != nil { return nil, err } - return &HeaderTransactor{contract: contract}, nil + return &DomainNotaryRegistryDomainNotaryAddedIterator{contract: _DomainNotaryRegistry.contract, event: "DomainNotaryAdded", logs: logs, sub: sub}, nil } -// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. -func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { - contract, err := bindHeader(address, nil, nil, filterer) +// WatchDomainNotaryAdded is a free log subscription operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *DomainNotaryRegistryDomainNotaryAdded) (event.Subscription, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.WatchLogs(opts, "DomainNotaryAdded") if err != nil { return nil, err } - return &HeaderFilterer{contract: contract}, nil -} - -// bindHeader binds a generic wrapper to an already deployed contract. -func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HeaderABI)) - if err != nil { + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DomainNotaryRegistryDomainNotaryAdded) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDomainNotaryAdded is a log parse operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. +// +// Solidity: event DomainNotaryAdded(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) ParseDomainNotaryAdded(log types.Log) (*DomainNotaryRegistryDomainNotaryAdded, error) { + event := new(DomainNotaryRegistryDomainNotaryAdded) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + event.Raw = log + return event, nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) +// DomainNotaryRegistryDomainNotaryRemovedIterator is returned from FilterDomainNotaryRemoved and is used to iterate over the raw logs and unpacked data for DomainNotaryRemoved events raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryRemovedIterator struct { + Event *DomainNotaryRegistryDomainNotaryRemoved // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transfer(opts) +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(DomainNotaryRegistryDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Error() error { + return it.fail } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Header.Contract.contract.Call(opts, result, method, params...) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *DomainNotaryRegistryDomainNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Header.Contract.contract.Transfer(opts) +// DomainNotaryRegistryDomainNotaryRemoved represents a DomainNotaryRemoved event raised by the DomainNotaryRegistry contract. +type DomainNotaryRegistryDomainNotaryRemoved struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// Transact invokes the (paid) contract method with params as input values. -func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Header.Contract.contract.Transact(opts, method, params...) +// FilterDomainNotaryRemoved is a free log retrieval operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*DomainNotaryRegistryDomainNotaryRemovedIterator, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.FilterLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return &DomainNotaryRegistryDomainNotaryRemovedIterator{contract: _DomainNotaryRegistry.contract, event: "DomainNotaryRemoved", logs: logs, sub: sub}, nil } -// HomeMetaData contains all meta data concerning the Home contract. -var HomeMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enumHome.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "522ae002": "MAX_MESSAGE_BODY_BYTES()", - "ffa1ad74": "VERSION()", - "06661abd": "count()", - "f7560e40": "dispatch(uint32,bytes32,uint32,bytes,bytes)", - "7ea97f40": "historicalRoots(uint256)", - "0afe7f90": "improperAttestation(bytes)", - "c4d66de8": "initialize(address)", - "8d3638f4": "localDomain()", - "affed0e0": "nonce()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "ebf0c717": "root()", - "b7bc563e": "setSystemMessenger(address)", - "9d54f419": "setUpdater(address)", - "9776120e": "setUpdaterManager(address)", - "c19d93fb": "state()", - "36e104de": "suggestUpdate()", - "ccbdf9c9": "systemMessenger()", - "f2fde38b": "transferOwnership(address)", - "fd54b228": "tree()", - "df034cd0": "updater()", - "9df6c8e1": "updaterManager()", - }, - Bin: "0x60a06040523480156200001157600080fd5b50604051620036d9380380620036d9833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b60805161363d6200009c6000396000818161025e01528181610d9c01526117a3015261363d6000f3fe6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220b3b337c9ceb3f8e191b14a91c40b33fb4e8d91c3e456e5e6bcdea6b2f771e7e464736f6c634300080d0033", +// WatchDomainNotaryRemoved is a free log subscription operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *DomainNotaryRegistryDomainNotaryRemoved) (event.Subscription, error) { + + logs, sub, err := _DomainNotaryRegistry.contract.WatchLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(DomainNotaryRegistryDomainNotaryRemoved) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// HomeABI is the input ABI used to generate the binding from. -// Deprecated: Use HomeMetaData.ABI instead. -var HomeABI = HomeMetaData.ABI +// ParseDomainNotaryRemoved is a log parse operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_DomainNotaryRegistry *DomainNotaryRegistryFilterer) ParseDomainNotaryRemoved(log types.Log) (*DomainNotaryRegistryDomainNotaryRemoved, error) { + event := new(DomainNotaryRegistryDomainNotaryRemoved) + if err := _DomainNotaryRegistry.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} -// Deprecated: Use HomeMetaData.Sigs instead. -// HomeFuncSigs maps the 4-byte function signature to its string representation. -var HomeFuncSigs = HomeMetaData.Sigs +// ECDSAMetaData contains all meta data concerning the ECDSA contract. +var ECDSAMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200d08df708f0e20acb05557a8bfb4fdaa5d834a3c76f47cf5ef5263ca0795947164736f6c634300080d0033", +} -// HomeBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use HomeMetaData.Bin instead. -var HomeBin = HomeMetaData.Bin +// ECDSAABI is the input ABI used to generate the binding from. +// Deprecated: Use ECDSAMetaData.ABI instead. +var ECDSAABI = ECDSAMetaData.ABI -// DeployHome deploys a new Ethereum contract, binding an instance of Home to it. -func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *Home, error) { - parsed, err := HomeMetaData.GetAbi() +// ECDSABin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ECDSAMetaData.Bin instead. +var ECDSABin = ECDSAMetaData.Bin + +// DeployECDSA deploys a new Ethereum contract, binding an instance of ECDSA to it. +func DeployECDSA(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *ECDSA, error) { + parsed, err := ECDSAMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -1705,111 +2025,111 @@ func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDom return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HomeBin), backend, _localDomain) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ECDSABin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil + return address, tx, &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil } -// Home is an auto generated Go binding around an Ethereum contract. -type Home struct { - HomeCaller // Read-only binding to the contract - HomeTransactor // Write-only binding to the contract - HomeFilterer // Log filterer for contract events +// ECDSA is an auto generated Go binding around an Ethereum contract. +type ECDSA struct { + ECDSACaller // Read-only binding to the contract + ECDSATransactor // Write-only binding to the contract + ECDSAFilterer // Log filterer for contract events } -// HomeCaller is an auto generated read-only Go binding around an Ethereum contract. -type HomeCaller struct { +// ECDSACaller is an auto generated read-only Go binding around an Ethereum contract. +type ECDSACaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeTransactor is an auto generated write-only Go binding around an Ethereum contract. -type HomeTransactor struct { +// ECDSATransactor is an auto generated write-only Go binding around an Ethereum contract. +type ECDSATransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type HomeFilterer struct { +// ECDSAFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ECDSAFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeSession is an auto generated Go binding around an Ethereum contract, +// ECDSASession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type HomeSession struct { - Contract *Home // Generic contract binding to set the session for +type ECDSASession struct { + Contract *ECDSA // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// ECDSACallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type HomeCallerSession struct { - Contract *HomeCaller // Generic contract caller binding to set the session for +type ECDSACallerSession struct { + Contract *ECDSACaller // Generic contract caller binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session } -// HomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// ECDSATransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type HomeTransactorSession struct { - Contract *HomeTransactor // Generic contract transactor binding to set the session for +type ECDSATransactorSession struct { + Contract *ECDSATransactor // Generic contract transactor binding to set the session for TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// HomeRaw is an auto generated low-level Go binding around an Ethereum contract. -type HomeRaw struct { - Contract *Home // Generic contract binding to access the raw methods on -} - -// HomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type HomeCallerRaw struct { - Contract *HomeCaller // Generic read-only contract binding to access the raw methods on +// ECDSARaw is an auto generated low-level Go binding around an Ethereum contract. +type ECDSARaw struct { + Contract *ECDSA // Generic contract binding to access the raw methods on } -// HomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type HomeTransactorRaw struct { - Contract *HomeTransactor // Generic write-only contract binding to access the raw methods on +// ECDSACallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ECDSACallerRaw struct { + Contract *ECDSACaller // Generic read-only contract binding to access the raw methods on } -// NewHome creates a new instance of Home, bound to a specific deployed contract. -func NewHome(address common.Address, backend bind.ContractBackend) (*Home, error) { - contract, err := bindHome(address, backend, backend, backend) +// ECDSATransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ECDSATransactorRaw struct { + Contract *ECDSATransactor // Generic write-only contract binding to access the raw methods on +} + +// NewECDSA creates a new instance of ECDSA, bound to a specific deployed contract. +func NewECDSA(address common.Address, backend bind.ContractBackend) (*ECDSA, error) { + contract, err := bindECDSA(address, backend, backend, backend) if err != nil { return nil, err } - return &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil + return &ECDSA{ECDSACaller: ECDSACaller{contract: contract}, ECDSATransactor: ECDSATransactor{contract: contract}, ECDSAFilterer: ECDSAFilterer{contract: contract}}, nil } -// NewHomeCaller creates a new read-only instance of Home, bound to a specific deployed contract. -func NewHomeCaller(address common.Address, caller bind.ContractCaller) (*HomeCaller, error) { - contract, err := bindHome(address, caller, nil, nil) +// NewECDSACaller creates a new read-only instance of ECDSA, bound to a specific deployed contract. +func NewECDSACaller(address common.Address, caller bind.ContractCaller) (*ECDSACaller, error) { + contract, err := bindECDSA(address, caller, nil, nil) if err != nil { return nil, err } - return &HomeCaller{contract: contract}, nil + return &ECDSACaller{contract: contract}, nil } -// NewHomeTransactor creates a new write-only instance of Home, bound to a specific deployed contract. -func NewHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*HomeTransactor, error) { - contract, err := bindHome(address, nil, transactor, nil) +// NewECDSATransactor creates a new write-only instance of ECDSA, bound to a specific deployed contract. +func NewECDSATransactor(address common.Address, transactor bind.ContractTransactor) (*ECDSATransactor, error) { + contract, err := bindECDSA(address, nil, transactor, nil) if err != nil { return nil, err } - return &HomeTransactor{contract: contract}, nil + return &ECDSATransactor{contract: contract}, nil } -// NewHomeFilterer creates a new log filterer instance of Home, bound to a specific deployed contract. -func NewHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*HomeFilterer, error) { - contract, err := bindHome(address, nil, nil, filterer) +// NewECDSAFilterer creates a new log filterer instance of ECDSA, bound to a specific deployed contract. +func NewECDSAFilterer(address common.Address, filterer bind.ContractFilterer) (*ECDSAFilterer, error) { + contract, err := bindECDSA(address, nil, nil, filterer) if err != nil { return nil, err } - return &HomeFilterer{contract: contract}, nil + return &ECDSAFilterer{contract: contract}, nil } -// bindHome binds a generic wrapper to an already deployed contract. -func bindHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(HomeABI)) +// bindECDSA binds a generic wrapper to an already deployed contract. +func bindECDSA(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ECDSAABI)) if err != nil { return nil, err } @@ -1820,370 +2140,432 @@ func bindHome(address common.Address, caller bind.ContractCaller, transactor bin // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Home *HomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Home.Contract.HomeCaller.contract.Call(opts, result, method, params...) +func (_ECDSA *ECDSARaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ECDSA.Contract.ECDSACaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Home *HomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.Contract.HomeTransactor.contract.Transfer(opts) +func (_ECDSA *ECDSARaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ECDSA.Contract.ECDSATransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Home *HomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Home.Contract.HomeTransactor.contract.Transact(opts, method, params...) +func (_ECDSA *ECDSARaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ECDSA.Contract.ECDSATransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Home *HomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Home.Contract.contract.Call(opts, result, method, params...) +func (_ECDSA *ECDSACallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ECDSA.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Home *HomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.Contract.contract.Transfer(opts) +func (_ECDSA *ECDSATransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ECDSA.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Home *HomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Home.Contract.contract.Transact(opts, method, params...) +func (_ECDSA *ECDSATransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ECDSA.Contract.contract.Transact(opts, method, params...) } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeCaller) MAXMESSAGEBODYBYTES(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "MAX_MESSAGE_BODY_BYTES") +// EnumerableSetMetaData contains all meta data concerning the EnumerableSet contract. +var EnumerableSetMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212203ec4b2937303fd20eb43d43650d3288d4f4d8d01fbca0f6e933f10a1d93c030e64736f6c634300080d0033", +} - if err != nil { - return *new(*big.Int), err - } +// EnumerableSetABI is the input ABI used to generate the binding from. +// Deprecated: Use EnumerableSetMetaData.ABI instead. +var EnumerableSetABI = EnumerableSetMetaData.ABI - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) +// EnumerableSetBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use EnumerableSetMetaData.Bin instead. +var EnumerableSetBin = EnumerableSetMetaData.Bin - return out0, err +// DeployEnumerableSet deploys a new Ethereum contract, binding an instance of EnumerableSet to it. +func DeployEnumerableSet(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *EnumerableSet, error) { + parsed, err := EnumerableSetMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EnumerableSetBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { - return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) +// EnumerableSet is an auto generated Go binding around an Ethereum contract. +type EnumerableSet struct { + EnumerableSetCaller // Read-only binding to the contract + EnumerableSetTransactor // Write-only binding to the contract + EnumerableSetFilterer // Log filterer for contract events } -// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. -// -// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) -func (_Home *HomeCallerSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { - return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) +// EnumerableSetCaller is an auto generated read-only Go binding around an Ethereum contract. +type EnumerableSetCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeCaller) VERSION(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "VERSION") +// EnumerableSetTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EnumerableSetTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - if err != nil { - return *new(uint8), err - } +// EnumerableSetFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EnumerableSetFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) +// EnumerableSetSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type EnumerableSetSession struct { + Contract *EnumerableSet // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - return out0, err +// EnumerableSetCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type EnumerableSetCallerSession struct { + Contract *EnumerableSetCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} +// EnumerableSetTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type EnumerableSetTransactorSession struct { + Contract *EnumerableSetTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeSession) VERSION() (uint8, error) { - return _Home.Contract.VERSION(&_Home.CallOpts) +// EnumerableSetRaw is an auto generated low-level Go binding around an Ethereum contract. +type EnumerableSetRaw struct { + Contract *EnumerableSet // Generic contract binding to access the raw methods on } -// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. -// -// Solidity: function VERSION() view returns(uint8) -func (_Home *HomeCallerSession) VERSION() (uint8, error) { - return _Home.Contract.VERSION(&_Home.CallOpts) +// EnumerableSetCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EnumerableSetCallerRaw struct { + Contract *EnumerableSetCaller // Generic read-only contract binding to access the raw methods on } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeCaller) Count(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "count") +// EnumerableSetTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EnumerableSetTransactorRaw struct { + Contract *EnumerableSetTransactor // Generic write-only contract binding to access the raw methods on +} +// NewEnumerableSet creates a new instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSet(address common.Address, backend bind.ContractBackend) (*EnumerableSet, error) { + contract, err := bindEnumerableSet(address, backend, backend, backend) if err != nil { - return *new(*big.Int), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - + return &EnumerableSet{EnumerableSetCaller: EnumerableSetCaller{contract: contract}, EnumerableSetTransactor: EnumerableSetTransactor{contract: contract}, EnumerableSetFilterer: EnumerableSetFilterer{contract: contract}}, nil } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeSession) Count() (*big.Int, error) { - return _Home.Contract.Count(&_Home.CallOpts) +// NewEnumerableSetCaller creates a new read-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetCaller(address common.Address, caller bind.ContractCaller) (*EnumerableSetCaller, error) { + contract, err := bindEnumerableSet(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EnumerableSetCaller{contract: contract}, nil } -// Count is a free data retrieval call binding the contract method 0x06661abd. -// -// Solidity: function count() view returns(uint256) -func (_Home *HomeCallerSession) Count() (*big.Int, error) { - return _Home.Contract.Count(&_Home.CallOpts) +// NewEnumerableSetTransactor creates a new write-only instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetTransactor(address common.Address, transactor bind.ContractTransactor) (*EnumerableSetTransactor, error) { + contract, err := bindEnumerableSet(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EnumerableSetTransactor{contract: contract}, nil } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "historicalRoots", arg0) +// NewEnumerableSetFilterer creates a new log filterer instance of EnumerableSet, bound to a specific deployed contract. +func NewEnumerableSetFilterer(address common.Address, filterer bind.ContractFilterer) (*EnumerableSetFilterer, error) { + contract, err := bindEnumerableSet(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EnumerableSetFilterer{contract: contract}, nil +} +// bindEnumerableSet binds a generic wrapper to an already deployed contract. +func bindEnumerableSet(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(EnumerableSetABI)) if err != nil { - return *new([32]byte), err + return nil, err } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EnumerableSet *EnumerableSetRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.EnumerableSetCaller.contract.Call(opts, result, method, params...) +} - return out0, err +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EnumerableSet *EnumerableSetRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transfer(opts) +} +// Transact invokes the (paid) contract method with params as input values. +func (_EnumerableSet *EnumerableSetRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.EnumerableSetTransactor.contract.Transact(opts, method, params...) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_EnumerableSet *EnumerableSetCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _EnumerableSet.Contract.contract.Call(opts, result, method, params...) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_Home *HomeCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_EnumerableSet *EnumerableSetTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transfer(opts) } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "localDomain") +// Transact invokes the (paid) contract method with params as input values. +func (_EnumerableSet *EnumerableSetTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _EnumerableSet.Contract.contract.Transact(opts, method, params...) +} + +// GuardRegistryMetaData contains all meta data concerning the GuardRegistry contract. +var GuardRegistryMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "9fe03fa2": "allGuards()", + "629ddf69": "getGuard(uint256)", + "246c2449": "guardsAmount()", + }, + Bin: "0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212206f43888a818e9d4f992c4856f348d474f6697c6995f67db46b7bc57aa6c3098564736f6c634300080d0033", +} + +// GuardRegistryABI is the input ABI used to generate the binding from. +// Deprecated: Use GuardRegistryMetaData.ABI instead. +var GuardRegistryABI = GuardRegistryMetaData.ABI +// Deprecated: Use GuardRegistryMetaData.Sigs instead. +// GuardRegistryFuncSigs maps the 4-byte function signature to its string representation. +var GuardRegistryFuncSigs = GuardRegistryMetaData.Sigs + +// GuardRegistryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use GuardRegistryMetaData.Bin instead. +var GuardRegistryBin = GuardRegistryMetaData.Bin + +// DeployGuardRegistry deploys a new Ethereum contract, binding an instance of GuardRegistry to it. +func DeployGuardRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *GuardRegistry, error) { + parsed, err := GuardRegistryMetaData.GetAbi() if err != nil { - return *new(uint32), err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(GuardRegistryBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil +} - return out0, err +// GuardRegistry is an auto generated Go binding around an Ethereum contract. +type GuardRegistry struct { + GuardRegistryCaller // Read-only binding to the contract + GuardRegistryTransactor // Write-only binding to the contract + GuardRegistryFilterer // Log filterer for contract events +} +// GuardRegistryCaller is an auto generated read-only Go binding around an Ethereum contract. +type GuardRegistryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeSession) LocalDomain() (uint32, error) { - return _Home.Contract.LocalDomain(&_Home.CallOpts) +// GuardRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type GuardRegistryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_Home *HomeCallerSession) LocalDomain() (uint32, error) { - return _Home.Contract.LocalDomain(&_Home.CallOpts) +// GuardRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type GuardRegistryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeCaller) Nonce(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "nonce") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) +// GuardRegistrySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type GuardRegistrySession struct { + Contract *GuardRegistry // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - return out0, err +// GuardRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type GuardRegistryCallerSession struct { + Contract *GuardRegistryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} +// GuardRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type GuardRegistryTransactorSession struct { + Contract *GuardRegistryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeSession) Nonce() (uint32, error) { - return _Home.Contract.Nonce(&_Home.CallOpts) +// GuardRegistryRaw is an auto generated low-level Go binding around an Ethereum contract. +type GuardRegistryRaw struct { + Contract *GuardRegistry // Generic contract binding to access the raw methods on } -// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. -// -// Solidity: function nonce() view returns(uint32) -func (_Home *HomeCallerSession) Nonce() (uint32, error) { - return _Home.Contract.Nonce(&_Home.CallOpts) +// GuardRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type GuardRegistryCallerRaw struct { + Contract *GuardRegistryCaller // Generic read-only contract binding to access the raw methods on } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "owner") +// GuardRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type GuardRegistryTransactorRaw struct { + Contract *GuardRegistryTransactor // Generic write-only contract binding to access the raw methods on +} +// NewGuardRegistry creates a new instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistry(address common.Address, backend bind.ContractBackend) (*GuardRegistry, error) { + contract, err := bindGuardRegistry(address, backend, backend, backend) if err != nil { - return *new(common.Address), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - + return &GuardRegistry{GuardRegistryCaller: GuardRegistryCaller{contract: contract}, GuardRegistryTransactor: GuardRegistryTransactor{contract: contract}, GuardRegistryFilterer: GuardRegistryFilterer{contract: contract}}, nil } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeSession) Owner() (common.Address, error) { - return _Home.Contract.Owner(&_Home.CallOpts) +// NewGuardRegistryCaller creates a new read-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryCaller(address common.Address, caller bind.ContractCaller) (*GuardRegistryCaller, error) { + contract, err := bindGuardRegistry(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &GuardRegistryCaller{contract: contract}, nil } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_Home *HomeCallerSession) Owner() (common.Address, error) { - return _Home.Contract.Owner(&_Home.CallOpts) +// NewGuardRegistryTransactor creates a new write-only instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*GuardRegistryTransactor, error) { + contract, err := bindGuardRegistry(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &GuardRegistryTransactor{contract: contract}, nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeCaller) Root(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "root") - +// NewGuardRegistryFilterer creates a new log filterer instance of GuardRegistry, bound to a specific deployed contract. +func NewGuardRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*GuardRegistryFilterer, error) { + contract, err := bindGuardRegistry(address, nil, nil, filterer) if err != nil { - return *new([32]byte), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - + return &GuardRegistryFilterer{contract: contract}, nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeSession) Root() ([32]byte, error) { - return _Home.Contract.Root(&_Home.CallOpts) +// bindGuardRegistry binds a generic wrapper to an already deployed contract. +func bindGuardRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(GuardRegistryABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_Home *HomeCallerSession) Root() ([32]byte, error) { - return _Home.Contract.Root(&_Home.CallOpts) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GuardRegistry *GuardRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.GuardRegistryCaller.contract.Call(opts, result, method, params...) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeCaller) State(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "state") - - if err != nil { - return *new(uint8), err - } - - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GuardRegistry *GuardRegistryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transfer(opts) +} - return out0, err +// Transact invokes the (paid) contract method with params as input values. +func (_GuardRegistry *GuardRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.GuardRegistryTransactor.contract.Transact(opts, method, params...) +} +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_GuardRegistry *GuardRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _GuardRegistry.Contract.contract.Call(opts, result, method, params...) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeSession) State() (uint8, error) { - return _Home.Contract.State(&_Home.CallOpts) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_GuardRegistry *GuardRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transfer(opts) } -// State is a free data retrieval call binding the contract method 0xc19d93fb. -// -// Solidity: function state() view returns(uint8) -func (_Home *HomeCallerSession) State() (uint8, error) { - return _Home.Contract.State(&_Home.CallOpts) +// Transact invokes the (paid) contract method with params as input values. +func (_GuardRegistry *GuardRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _GuardRegistry.Contract.contract.Transact(opts, method, params...) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeCaller) SuggestUpdate(opts *bind.CallOpts) (struct { - Nonce uint32 - Root [32]byte -}, error) { +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "suggestUpdate") + err := _GuardRegistry.contract.Call(opts, &out, "allGuards") - outstruct := new(struct { - Nonce uint32 - Root [32]byte - }) if err != nil { - return *outstruct, err + return *new([]common.Address), err } - outstruct.Nonce = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) - return *outstruct, err + return out0, err } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeSession) SuggestUpdate() (struct { - Nonce uint32 - Root [32]byte -}, error) { - return _Home.Contract.SuggestUpdate(&_Home.CallOpts) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistrySession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) -func (_Home *HomeCallerSession) SuggestUpdate() (struct { - Nonce uint32 - Root [32]byte -}, error) { - return _Home.Contract.SuggestUpdate(&_Home.CallOpts) +// Solidity: function allGuards() view returns(address[]) +func (_GuardRegistry *GuardRegistryCallerSession) AllGuards() ([]common.Address, error) { + return _GuardRegistry.Contract.AllGuards(&_GuardRegistry.CallOpts) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "systemMessenger") + err := _GuardRegistry.contract.Call(opts, &out, "getGuard", _index) if err != nil { return *new(common.Address), err @@ -2195,26 +2577,26 @@ func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, e } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeSession) SystemMessenger() (common.Address, error) { - return _Home.Contract.SystemMessenger(&_Home.CallOpts) +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistrySession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: function systemMessenger() view returns(address) -func (_Home *HomeCallerSession) SystemMessenger() (common.Address, error) { - return _Home.Contract.SystemMessenger(&_Home.CallOpts) +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_GuardRegistry *GuardRegistryCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _GuardRegistry.Contract.GetGuard(&_GuardRegistry.CallOpts, _index) } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _Home.contract.Call(opts, &out, "tree") + err := _GuardRegistry.contract.Call(opts, &out, "guardsAmount") if err != nil { return *new(*big.Int), err @@ -2226,253 +2608,157 @@ func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeSession) Tree() (*big.Int, error) { - return _Home.Contract.Tree(&_Home.CallOpts) +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistrySession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: function tree() view returns(uint256 count) -func (_Home *HomeCallerSession) Tree() (*big.Int, error) { - return _Home.Contract.Tree(&_Home.CallOpts) +// Solidity: function guardsAmount() view returns(uint256) +func (_GuardRegistry *GuardRegistryCallerSession) GuardsAmount() (*big.Int, error) { + return _GuardRegistry.Contract.GuardsAmount(&_GuardRegistry.CallOpts) } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "updater") +// GuardRegistryGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the GuardRegistry contract. +type GuardRegistryGuardAddedIterator struct { + Event *GuardRegistryGuardAdded // Event containing the contract specifics and raw log - if err != nil { - return *new(common.Address), err + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *GuardRegistryGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GuardRegistryGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - return out0, err + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GuardRegistryGuardAddedIterator) Error() error { + return it.fail } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeSession) Updater() (common.Address, error) { - return _Home.Contract.Updater(&_Home.CallOpts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GuardRegistryGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_Home *HomeCallerSession) Updater() (common.Address, error) { - return _Home.Contract.Updater(&_Home.CallOpts) +// GuardRegistryGuardAdded represents a GuardAdded event raised by the GuardRegistry contract. +type GuardRegistryGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeCaller) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _Home.contract.Call(opts, &out, "updaterManager") +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*GuardRegistryGuardAddedIterator, error) { + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardAdded") if err != nil { - return *new(common.Address), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - + return &GuardRegistryGuardAddedIterator{contract: _GuardRegistry.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeSession) UpdaterManager() (common.Address, error) { - return _Home.Contract.UpdaterManager(&_Home.CallOpts) -} - -// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. -// -// Solidity: function updaterManager() view returns(address) -func (_Home *HomeCallerSession) UpdaterManager() (common.Address, error) { - return _Home.Contract.UpdaterManager(&_Home.CallOpts) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeTransactor) Dispatch(opts *bind.TransactOpts, _destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "dispatch", _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. -// -// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() -func (_Home *HomeTransactorSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { - return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeTransactor) ImproperAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "improperAttestation", _attestation) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { - return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) -} - -// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. -// -// Solidity: function improperAttestation(bytes _attestation) returns(bool) -func (_Home *HomeTransactorSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { - return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeTransactor) Initialize(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "initialize", _updaterManager) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) -} - -// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. -// -// Solidity: function initialize(address _updaterManager) returns() -func (_Home *HomeTransactorSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "renounceOwnership") -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeSession) RenounceOwnership() (*types.Transaction, error) { - return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) -} - -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_Home *HomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setSystemMessenger", _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) -} - -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. -// -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_Home *HomeTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setUpdater", _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) -} - -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updater) returns() -func (_Home *HomeTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeTransactor) SetUpdaterManager(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "setUpdaterManager", _updaterManager) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) -} - -// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. -// -// Solidity: function setUpdaterManager(address _updaterManager) returns() -func (_Home *HomeTransactorSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { - return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) -} +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardAdded) (event.Subscription, error) { -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _Home.contract.Transact(opts, "transferOwnership", newOwner) -} + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardAdded") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_Home *HomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) +// Solidity: event GuardAdded(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardAdded(log types.Log) (*GuardRegistryGuardAdded, error) { + event := new(GuardRegistryGuardAdded) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// HomeDispatchIterator is returned from FilterDispatch and is used to iterate over the raw logs and unpacked data for Dispatch events raised by the Home contract. -type HomeDispatchIterator struct { - Event *HomeDispatch // Event containing the contract specifics and raw log +// GuardRegistryGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the GuardRegistry contract. +type GuardRegistryGuardRemovedIterator struct { + Event *GuardRegistryGuardRemoved // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -2486,7 +2772,7 @@ type HomeDispatchIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *HomeDispatchIterator) Next() bool { +func (it *GuardRegistryGuardRemovedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -2495,7 +2781,7 @@ func (it *HomeDispatchIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(HomeDispatch) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2510,7 +2796,7 @@ func (it *HomeDispatchIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(HomeDispatch) + it.Event = new(GuardRegistryGuardRemoved) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2526,71 +2812,41 @@ func (it *HomeDispatchIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeDispatchIterator) Error() error { +func (it *GuardRegistryGuardRemovedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *HomeDispatchIterator) Close() error { +func (it *GuardRegistryGuardRemovedIterator) Close() error { it.sub.Unsubscribe() return nil } -// HomeDispatch represents a Dispatch event raised by the Home contract. -type HomeDispatch struct { - MessageHash [32]byte - LeafIndex *big.Int - DestinationAndNonce uint64 - Tips []byte - Message []byte - Raw types.Log // Blockchain specific contextual infos +// GuardRegistryGuardRemoved represents a GuardRemoved event raised by the GuardRegistry contract. +type GuardRegistryGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterDispatch is a free log retrieval operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (*HomeDispatchIterator, error) { - - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) - } - var leafIndexRule []interface{} - for _, leafIndexItem := range leafIndex { - leafIndexRule = append(leafIndexRule, leafIndexItem) - } - var destinationAndNonceRule []interface{} - for _, destinationAndNonceItem := range destinationAndNonce { - destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) - } +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*GuardRegistryGuardRemovedIterator, error) { - logs, sub, err := _Home.contract.FilterLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + logs, sub, err := _GuardRegistry.contract.FilterLogs(opts, "GuardRemoved") if err != nil { return nil, err } - return &HomeDispatchIterator{contract: _Home.contract, event: "Dispatch", logs: logs, sub: sub}, nil + return &GuardRegistryGuardRemovedIterator{contract: _GuardRegistry.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil } -// WatchDispatch is a free log subscription operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *HomeDispatch, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (event.Subscription, error) { - - var messageHashRule []interface{} - for _, messageHashItem := range messageHash { - messageHashRule = append(messageHashRule, messageHashItem) - } - var leafIndexRule []interface{} - for _, leafIndexItem := range leafIndex { - leafIndexRule = append(leafIndexRule, leafIndexItem) - } - var destinationAndNonceRule []interface{} - for _, destinationAndNonceItem := range destinationAndNonce { - destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) - } +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *GuardRegistryGuardRemoved) (event.Subscription, error) { - logs, sub, err := _Home.contract.WatchLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + logs, sub, err := _GuardRegistry.contract.WatchLogs(opts, "GuardRemoved") if err != nil { return nil, err } @@ -2600,8 +2856,8 @@ func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *Home select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(HomeDispatch) - if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return err } event.Raw = log @@ -2622,1569 +2878,1335 @@ func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *Home }), nil } -// ParseDispatch is a log parse operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. // -// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) -func (_Home *HomeFilterer) ParseDispatch(log types.Log) (*HomeDispatch, error) { - event := new(HomeDispatch) - if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { +// Solidity: event GuardRemoved(address guard) +func (_GuardRegistry *GuardRegistryFilterer) ParseGuardRemoved(log types.Log) (*GuardRegistryGuardRemoved, error) { + event := new(GuardRegistryGuardRemoved) + if err := _GuardRegistry.contract.UnpackLog(event, "GuardRemoved", log); err != nil { return nil, err } event.Raw = log return event, nil } -// HomeImproperAttestationIterator is returned from FilterImproperAttestation and is used to iterate over the raw logs and unpacked data for ImproperAttestation events raised by the Home contract. -type HomeImproperAttestationIterator struct { - Event *HomeImproperAttestation // Event containing the contract specifics and raw log +// HeaderMetaData contains all meta data concerning the Header contract. +var HeaderMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122071475f0137e7fab40ea940971931a3cd0659ab8643a6c45696eed4d5b03c44dd64736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// HeaderABI is the input ABI used to generate the binding from. +// Deprecated: Use HeaderMetaData.ABI instead. +var HeaderABI = HeaderMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// HeaderBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HeaderMetaData.Bin instead. +var HeaderBin = HeaderMetaData.Bin -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeImproperAttestationIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// DeployHeader deploys a new Ethereum contract, binding an instance of Header to it. +func DeployHeader(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Header, error) { + parsed, err := HeaderMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeImproperAttestation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeImproperAttestation) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HeaderBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } + return address, tx, &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeImproperAttestationIterator) Error() error { - return it.fail +// Header is an auto generated Go binding around an Ethereum contract. +type Header struct { + HeaderCaller // Read-only binding to the contract + HeaderTransactor // Write-only binding to the contract + HeaderFilterer // Log filterer for contract events } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeImproperAttestationIterator) Close() error { - it.sub.Unsubscribe() - return nil +// HeaderCaller is an auto generated read-only Go binding around an Ethereum contract. +type HeaderCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// HomeImproperAttestation represents a ImproperAttestation event raised by the Home contract. -type HomeImproperAttestation struct { - Updater common.Address - Attestation []byte - Raw types.Log // Blockchain specific contextual infos +// HeaderTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HeaderTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) FilterImproperAttestation(opts *bind.FilterOpts) (*HomeImproperAttestationIterator, error) { +// HeaderFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HeaderFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs, sub, err := _Home.contract.FilterLogs(opts, "ImproperAttestation") +// HeaderSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type HeaderSession struct { + Contract *Header // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// HeaderCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type HeaderCallerSession struct { + Contract *HeaderCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// HeaderTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type HeaderTransactorSession struct { + Contract *HeaderTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// HeaderRaw is an auto generated low-level Go binding around an Ethereum contract. +type HeaderRaw struct { + Contract *Header // Generic contract binding to access the raw methods on +} + +// HeaderCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HeaderCallerRaw struct { + Contract *HeaderCaller // Generic read-only contract binding to access the raw methods on +} + +// HeaderTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HeaderTransactorRaw struct { + Contract *HeaderTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewHeader creates a new instance of Header, bound to a specific deployed contract. +func NewHeader(address common.Address, backend bind.ContractBackend) (*Header, error) { + contract, err := bindHeader(address, backend, backend, backend) if err != nil { return nil, err } - return &HomeImproperAttestationIterator{contract: _Home.contract, event: "ImproperAttestation", logs: logs, sub: sub}, nil + return &Header{HeaderCaller: HeaderCaller{contract: contract}, HeaderTransactor: HeaderTransactor{contract: contract}, HeaderFilterer: HeaderFilterer{contract: contract}}, nil } -// WatchImproperAttestation is a free log subscription operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *HomeImproperAttestation) (event.Subscription, error) { - - logs, sub, err := _Home.contract.WatchLogs(opts, "ImproperAttestation") +// NewHeaderCaller creates a new read-only instance of Header, bound to a specific deployed contract. +func NewHeaderCaller(address common.Address, caller bind.ContractCaller) (*HeaderCaller, error) { + contract, err := bindHeader(address, caller, nil, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeImproperAttestation) - if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { - return err - } - event.Raw = log + return &HeaderCaller{contract: contract}, nil +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// NewHeaderTransactor creates a new write-only instance of Header, bound to a specific deployed contract. +func NewHeaderTransactor(address common.Address, transactor bind.ContractTransactor) (*HeaderTransactor, error) { + contract, err := bindHeader(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &HeaderTransactor{contract: contract}, nil } -// ParseImproperAttestation is a log parse operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. -// -// Solidity: event ImproperAttestation(address updater, bytes attestation) -func (_Home *HomeFilterer) ParseImproperAttestation(log types.Log) (*HomeImproperAttestation, error) { - event := new(HomeImproperAttestation) - if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { +// NewHeaderFilterer creates a new log filterer instance of Header, bound to a specific deployed contract. +func NewHeaderFilterer(address common.Address, filterer bind.ContractFilterer) (*HeaderFilterer, error) { + contract, err := bindHeader(address, nil, nil, filterer) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &HeaderFilterer{contract: contract}, nil } -// HomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Home contract. -type HomeInitializedIterator struct { - Event *HomeInitialized // Event containing the contract specifics and raw log +// bindHeader binds a generic wrapper to an already deployed contract. +func bindHeader(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HeaderABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Header *HeaderRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.HeaderCaller.contract.Call(opts, result, method, params...) +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Header *HeaderRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transfer(opts) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transact invokes the (paid) contract method with params as input values. +func (_Header *HeaderRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.HeaderTransactor.contract.Transact(opts, method, params...) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Header *HeaderCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Header.Contract.contract.Call(opts, result, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeInitializedIterator) Error() error { - return it.fail +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Header *HeaderTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Header.Contract.contract.Transfer(opts) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transact invokes the (paid) contract method with params as input values. +func (_Header *HeaderTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Header.Contract.contract.Transact(opts, method, params...) } -// HomeInitialized represents a Initialized event raised by the Home contract. -type HomeInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// HomeMetaData contains all meta data concerning the Home contract. +var HomeMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enumHome.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contractIUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "522ae002": "MAX_MESSAGE_BODY_BYTES()", + "ffa1ad74": "VERSION()", + "9fe03fa2": "allGuards()", + "9817e315": "allNotaries()", + "06661abd": "count()", + "f7560e40": "dispatch(uint32,bytes32,uint32,bytes,bytes)", + "629ddf69": "getGuard(uint256)", + "c07dc7f5": "getNotary(uint256)", + "246c2449": "guardsAmount()", + "7ea97f40": "historicalRoots(uint256)", + "0afe7f90": "improperAttestation(bytes)", + "c4d66de8": "initialize(address)", + "8d3638f4": "localDomain()", + "affed0e0": "nonce()", + "8e62e9ef": "notariesAmount()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "ebf0c717": "root()", + "b7bc563e": "setSystemMessenger(address)", + "9d54f419": "setUpdater(address)", + "9776120e": "setUpdaterManager(address)", + "c19d93fb": "state()", + "36e104de": "suggestUpdate()", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + "fd54b228": "tree()", + "9df6c8e1": "updaterManager()", + }, + Bin: "0x60c06040523480156200001157600080fd5b50604051620038c7380380620038c7833981016040819052620000349162000048565b63ffffffff16608081905260a05262000077565b6000602082840312156200005b57600080fd5b815163ffffffff811681146200007057600080fd5b9392505050565b60805160a051613823620000a460003960006118a70152600081816102ef0152610ea501526138236000f3fe6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea2646970667358221220ba13c1faec0e4c3a099925d7c203efd3f588ac7f865d7d75c54f5d2a2b204e3564736f6c634300080d0033", } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*HomeInitializedIterator, error) { +// HomeABI is the input ABI used to generate the binding from. +// Deprecated: Use HomeMetaData.ABI instead. +var HomeABI = HomeMetaData.ABI - logs, sub, err := _Home.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return &HomeInitializedIterator{contract: _Home.contract, event: "Initialized", logs: logs, sub: sub}, nil -} +// Deprecated: Use HomeMetaData.Sigs instead. +// HomeFuncSigs maps the 4-byte function signature to its string representation. +var HomeFuncSigs = HomeMetaData.Sigs -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *HomeInitialized) (event.Subscription, error) { +// HomeBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use HomeMetaData.Bin instead. +var HomeBin = HomeMetaData.Bin - logs, sub, err := _Home.contract.WatchLogs(opts, "Initialized") +// DeployHome deploys a new Ethereum contract, binding an instance of Home to it. +func DeployHome(auth *bind.TransactOpts, backend bind.ContractBackend, _localDomain uint32) (common.Address, *types.Transaction, *Home, error) { + parsed, err := HomeMetaData.GetAbi() if err != nil { - return nil, err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeInitialized) - if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(HomeBin), backend, _localDomain) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_Home *HomeFilterer) ParseInitialized(log types.Log) (*HomeInitialized, error) { - event := new(HomeInitialized) - if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Home is an auto generated Go binding around an Ethereum contract. +type Home struct { + HomeCaller // Read-only binding to the contract + HomeTransactor // Write-only binding to the contract + HomeFilterer // Log filterer for contract events } -// HomeNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the Home contract. -type HomeNewUpdaterIterator struct { - Event *HomeNewUpdater // Event containing the contract specifics and raw log +// HomeCaller is an auto generated read-only Go binding around an Ethereum contract. +type HomeCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// HomeTransactor is an auto generated write-only Go binding around an Ethereum contract. +type HomeTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// HomeFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type HomeFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// HomeSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type HomeSession struct { + Contract *Home // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// HomeCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type HomeCallerSession struct { + Contract *HomeCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// HomeTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type HomeTransactorSession struct { + Contract *HomeTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeNewUpdaterIterator) Error() error { - return it.fail +// HomeRaw is an auto generated low-level Go binding around an Ethereum contract. +type HomeRaw struct { + Contract *Home // Generic contract binding to access the raw methods on } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// HomeCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type HomeCallerRaw struct { + Contract *HomeCaller // Generic read-only contract binding to access the raw methods on } -// HomeNewUpdater represents a NewUpdater event raised by the Home contract. -type HomeNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// HomeTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type HomeTransactorRaw struct { + Contract *HomeTransactor // Generic write-only contract binding to access the raw methods on } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*HomeNewUpdaterIterator, error) { +// NewHome creates a new instance of Home, bound to a specific deployed contract. +func NewHome(address common.Address, backend bind.ContractBackend) (*Home, error) { + contract, err := bindHome(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Home{HomeCaller: HomeCaller{contract: contract}, HomeTransactor: HomeTransactor{contract: contract}, HomeFilterer: HomeFilterer{contract: contract}}, nil +} - logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdater") +// NewHomeCaller creates a new read-only instance of Home, bound to a specific deployed contract. +func NewHomeCaller(address common.Address, caller bind.ContractCaller) (*HomeCaller, error) { + contract, err := bindHome(address, caller, nil, nil) if err != nil { return nil, err } - return &HomeNewUpdaterIterator{contract: _Home.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &HomeCaller{contract: contract}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *HomeNewUpdater) (event.Subscription, error) { +// NewHomeTransactor creates a new write-only instance of Home, bound to a specific deployed contract. +func NewHomeTransactor(address common.Address, transactor bind.ContractTransactor) (*HomeTransactor, error) { + contract, err := bindHome(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &HomeTransactor{contract: contract}, nil +} - logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdater") +// NewHomeFilterer creates a new log filterer instance of Home, bound to a specific deployed contract. +func NewHomeFilterer(address common.Address, filterer bind.ContractFilterer) (*HomeFilterer, error) { + contract, err := bindHome(address, nil, nil, filterer) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeNewUpdater) - if err := _Home.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &HomeFilterer{contract: contract}, nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. -// -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_Home *HomeFilterer) ParseNewUpdater(log types.Log) (*HomeNewUpdater, error) { - event := new(HomeNewUpdater) - if err := _Home.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// bindHome binds a generic wrapper to an already deployed contract. +func bindHome(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(HomeABI)) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// HomeNewUpdaterManagerIterator is returned from FilterNewUpdaterManager and is used to iterate over the raw logs and unpacked data for NewUpdaterManager events raised by the Home contract. -type HomeNewUpdaterManagerIterator struct { - Event *HomeNewUpdaterManager // Event containing the contract specifics and raw log +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Home *HomeRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Home.Contract.HomeCaller.contract.Call(opts, result, method, params...) +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Home *HomeRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.Contract.HomeTransactor.contract.Transfer(opts) +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// Transact invokes the (paid) contract method with params as input values. +func (_Home *HomeRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Home.Contract.HomeTransactor.contract.Transact(opts, method, params...) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeNewUpdaterManagerIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdaterManager) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Home *HomeCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Home.Contract.contract.Call(opts, result, method, params...) +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeNewUpdaterManager) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Home *HomeTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.Contract.contract.Transfer(opts) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transact invokes the (paid) contract method with params as input values. +func (_Home *HomeTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Home.Contract.contract.Transact(opts, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeNewUpdaterManagerIterator) Error() error { - return it.fail +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeCaller) MAXMESSAGEBODYBYTES(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "MAX_MESSAGE_BODY_BYTES") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeNewUpdaterManagerIterator) Close() error { - it.sub.Unsubscribe() - return nil +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { + return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) } -// HomeNewUpdaterManager represents a NewUpdaterManager event raised by the Home contract. -type HomeNewUpdaterManager struct { - UpdaterManager common.Address - Raw types.Log // Blockchain specific contextual infos +// MAXMESSAGEBODYBYTES is a free data retrieval call binding the contract method 0x522ae002. +// +// Solidity: function MAX_MESSAGE_BODY_BYTES() view returns(uint256) +func (_Home *HomeCallerSession) MAXMESSAGEBODYBYTES() (*big.Int, error) { + return _Home.Contract.MAXMESSAGEBODYBYTES(&_Home.CallOpts) } -// FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) FilterNewUpdaterManager(opts *bind.FilterOpts) (*HomeNewUpdaterManagerIterator, error) { +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeCaller) VERSION(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "VERSION") - logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdaterManager") if err != nil { - return nil, err + return *new(uint8), err } - return &HomeNewUpdaterManagerIterator{contract: _Home.contract, event: "NewUpdaterManager", logs: logs, sub: sub}, nil + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + } -// WatchNewUpdaterManager is a free log subscription operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *HomeNewUpdaterManager) (event.Subscription, error) { +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeSession) VERSION() (uint8, error) { + return _Home.Contract.VERSION(&_Home.CallOpts) +} + +// VERSION is a free data retrieval call binding the contract method 0xffa1ad74. +// +// Solidity: function VERSION() view returns(uint8) +func (_Home *HomeCallerSession) VERSION() (uint8, error) { + return _Home.Contract.VERSION(&_Home.CallOpts) +} + +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeCaller) AllGuards(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "allGuards") - logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdaterManager") if err != nil { - return nil, err + return *new([]common.Address), err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeNewUpdaterManager) - if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + } -// ParseNewUpdaterManager is a log parse operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. // -// Solidity: event NewUpdaterManager(address updaterManager) -func (_Home *HomeFilterer) ParseNewUpdaterManager(log types.Log) (*HomeNewUpdaterManager, error) { - event := new(HomeNewUpdaterManager) - if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeSession) AllGuards() ([]common.Address, error) { + return _Home.Contract.AllGuards(&_Home.CallOpts) } -// HomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Home contract. -type HomeOwnershipTransferredIterator struct { - Event *HomeOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// AllGuards is a free data retrieval call binding the contract method 0x9fe03fa2. +// +// Solidity: function allGuards() view returns(address[]) +func (_Home *HomeCallerSession) AllGuards() ([]common.Address, error) { + return _Home.Contract.AllGuards(&_Home.CallOpts) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeCaller) AllNotaries(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "allNotaries") - default: - return false - } + if err != nil { + return *new([]common.Address), err } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeOwnershipTransferredIterator) Error() error { - return it.fail -} + return out0, err -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil } -// HomeOwnershipTransferred represents a OwnershipTransferred event raised by the Home contract. -type HomeOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. +// +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeSession) AllNotaries() ([]common.Address, error) { + return _Home.Contract.AllNotaries(&_Home.CallOpts) } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// AllNotaries is a free data retrieval call binding the contract method 0x9817e315. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*HomeOwnershipTransferredIterator, error) { +// Solidity: function allNotaries() view returns(address[]) +func (_Home *HomeCallerSession) AllNotaries() ([]common.Address, error) { + return _Home.Contract.AllNotaries(&_Home.CallOpts) +} - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_Home *HomeCaller) Count(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "count") - logs, sub, err := _Home.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { - return nil, err + return *new(*big.Int), err } - return &HomeOwnershipTransferredIterator{contract: _Home.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// Count is a free data retrieval call binding the contract method 0x06661abd. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *HomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { +// Solidity: function count() view returns(uint256) +func (_Home *HomeSession) Count() (*big.Int, error) { + return _Home.Contract.Count(&_Home.CallOpts) +} - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_Home *HomeCallerSession) Count() (*big.Int, error) { + return _Home.Contract.Count(&_Home.CallOpts) +} + +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeCaller) GetGuard(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "getGuard", _index) - logs, sub, err := _Home.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { - return nil, err + return *new(common.Address), err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeOwnershipTransferred) - if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Home *HomeFilterer) ParseOwnershipTransferred(log types.Log) (*HomeOwnershipTransferred, error) { - event := new(HomeOwnershipTransferred) - if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeSession) GetGuard(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetGuard(&_Home.CallOpts, _index) } -// HomeUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the Home contract. -type HomeUpdateIterator struct { - Event *HomeUpdate // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// GetGuard is a free data retrieval call binding the contract method 0x629ddf69. +// +// Solidity: function getGuard(uint256 _index) view returns(address) +func (_Home *HomeCallerSession) GetGuard(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetGuard(&_Home.CallOpts, _index) } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeUpdateIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeCaller) GetNotary(opts *bind.CallOpts, _index *big.Int) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "getNotary", _index) - default: - return false - } + if err != nil { + return *new(common.Address), err } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeUpdate) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeUpdateIterator) Error() error { - return it.fail -} + return out0, err -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeUpdateIterator) Close() error { - it.sub.Unsubscribe() - return nil } -// HomeUpdate represents a Update event raised by the Home contract. -type HomeUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. +// +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeSession) GetNotary(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetNotary(&_Home.CallOpts, _index) } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// GetNotary is a free data retrieval call binding the contract method 0xc07dc7f5. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*HomeUpdateIterator, error) { +// Solidity: function getNotary(uint256 _index) view returns(address) +func (_Home *HomeCallerSession) GetNotary(_index *big.Int) (common.Address, error) { + return _Home.Contract.GetNotary(&_Home.CallOpts, _index) +} - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeCaller) GuardsAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "guardsAmount") - logs, sub, err := _Home.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new(*big.Int), err } - return &HomeUpdateIterator{contract: _Home.contract, event: "Update", logs: logs, sub: sub}, nil + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *HomeUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeSession) GuardsAmount() (*big.Int, error) { + return _Home.Contract.GuardsAmount(&_Home.CallOpts) +} - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) - } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) - } +// GuardsAmount is a free data retrieval call binding the contract method 0x246c2449. +// +// Solidity: function guardsAmount() view returns(uint256) +func (_Home *HomeCallerSession) GuardsAmount() (*big.Int, error) { + return _Home.Contract.GuardsAmount(&_Home.CallOpts) +} + +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "historicalRoots", arg0) - logs, sub, err := _Home.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) if err != nil { - return nil, err + return *new([32]byte), err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeUpdate) - if err := _Home.contract.UnpackLog(event, "Update", log); err != nil { - return err - } - event.Raw = log - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_Home *HomeFilterer) ParseUpdate(log types.Log) (*HomeUpdate, error) { - event := new(HomeUpdate) - if err := _Home.contract.UnpackLog(event, "Update", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) } -// HomeUpdaterSlashedIterator is returned from FilterUpdaterSlashed and is used to iterate over the raw logs and unpacked data for UpdaterSlashed events raised by the Home contract. -type HomeUpdaterSlashedIterator struct { - Event *HomeUpdaterSlashed // Event containing the contract specifics and raw log +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_Home *HomeCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _Home.Contract.HistoricalRoots(&_Home.CallOpts, arg0) +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "localDomain") -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *HomeUpdaterSlashedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false + if err != nil { + return *new(uint32), err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(HomeUpdaterSlashed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(HomeUpdaterSlashed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} + return out0, err -// Error returns any retrieval or parsing error occurred during filtering. -func (it *HomeUpdaterSlashedIterator) Error() error { - return it.fail } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *HomeUpdaterSlashedIterator) Close() error { - it.sub.Unsubscribe() - return nil +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeSession) LocalDomain() (uint32, error) { + return _Home.Contract.LocalDomain(&_Home.CallOpts) } -// HomeUpdaterSlashed represents a UpdaterSlashed event raised by the Home contract. -type HomeUpdaterSlashed struct { - Updater common.Address - Reporter common.Address - Raw types.Log // Blockchain specific contextual infos +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_Home *HomeCallerSession) LocalDomain() (uint32, error) { + return _Home.Contract.LocalDomain(&_Home.CallOpts) } -// FilterUpdaterSlashed is a free log retrieval operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. // -// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) -func (_Home *HomeFilterer) FilterUpdaterSlashed(opts *bind.FilterOpts, updater []common.Address, reporter []common.Address) (*HomeUpdaterSlashedIterator, error) { - - var updaterRule []interface{} - for _, updaterItem := range updater { - updaterRule = append(updaterRule, updaterItem) - } - var reporterRule []interface{} - for _, reporterItem := range reporter { - reporterRule = append(reporterRule, reporterItem) - } +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeCaller) Nonce(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "nonce") - logs, sub, err := _Home.contract.FilterLogs(opts, "UpdaterSlashed", updaterRule, reporterRule) if err != nil { - return nil, err + return *new(uint32), err } - return &HomeUpdaterSlashedIterator{contract: _Home.contract, event: "UpdaterSlashed", logs: logs, sub: sub}, nil -} - -// WatchUpdaterSlashed is a free log subscription operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. -// -// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) -func (_Home *HomeFilterer) WatchUpdaterSlashed(opts *bind.WatchOpts, sink chan<- *HomeUpdaterSlashed, updater []common.Address, reporter []common.Address) (event.Subscription, error) { - var updaterRule []interface{} - for _, updaterItem := range updater { - updaterRule = append(updaterRule, updaterItem) - } - var reporterRule []interface{} - for _, reporterItem := range reporter { - reporterRule = append(reporterRule, reporterItem) - } + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - logs, sub, err := _Home.contract.WatchLogs(opts, "UpdaterSlashed", updaterRule, reporterRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(HomeUpdaterSlashed) - if err := _Home.contract.UnpackLog(event, "UpdaterSlashed", log); err != nil { - return err - } - event.Raw = log + return out0, err - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil } -// ParseUpdaterSlashed is a log parse operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. // -// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) -func (_Home *HomeFilterer) ParseUpdaterSlashed(log types.Log) (*HomeUpdaterSlashed, error) { - event := new(HomeUpdaterSlashed) - if err := _Home.contract.UnpackLog(event, "UpdaterSlashed", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeSession) Nonce() (uint32, error) { + return _Home.Contract.Nonce(&_Home.CallOpts) } -// ISystemMessengerMetaData contains all meta data concerning the ISystemMessenger contract. -var ISystemMessengerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enumISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "0d1e27a7": "sendSystemMessage(uint32,uint8,bytes)", - }, +// Nonce is a free data retrieval call binding the contract method 0xaffed0e0. +// +// Solidity: function nonce() view returns(uint32) +func (_Home *HomeCallerSession) Nonce() (uint32, error) { + return _Home.Contract.Nonce(&_Home.CallOpts) } -// ISystemMessengerABI is the input ABI used to generate the binding from. -// Deprecated: Use ISystemMessengerMetaData.ABI instead. -var ISystemMessengerABI = ISystemMessengerMetaData.ABI +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeCaller) NotariesAmount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "notariesAmount") -// Deprecated: Use ISystemMessengerMetaData.Sigs instead. -// ISystemMessengerFuncSigs maps the 4-byte function signature to its string representation. -var ISystemMessengerFuncSigs = ISystemMessengerMetaData.Sigs + if err != nil { + return *new(*big.Int), err + } -// ISystemMessenger is an auto generated Go binding around an Ethereum contract. -type ISystemMessenger struct { - ISystemMessengerCaller // Read-only binding to the contract - ISystemMessengerTransactor // Write-only binding to the contract - ISystemMessengerFilterer // Log filterer for contract events -} + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) -// ISystemMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. -type ISystemMessengerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} + return out0, err -// ISystemMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type ISystemMessengerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// ISystemMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type ISystemMessengerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeSession) NotariesAmount() (*big.Int, error) { + return _Home.Contract.NotariesAmount(&_Home.CallOpts) } -// ISystemMessengerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type ISystemMessengerSession struct { - Contract *ISystemMessenger // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// NotariesAmount is a free data retrieval call binding the contract method 0x8e62e9ef. +// +// Solidity: function notariesAmount() view returns(uint256) +func (_Home *HomeCallerSession) NotariesAmount() (*big.Int, error) { + return _Home.Contract.NotariesAmount(&_Home.CallOpts) } -// ISystemMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type ISystemMessengerCallerSession struct { - Contract *ISystemMessengerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "owner") -// ISystemMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type ISystemMessengerTransactorSession struct { - Contract *ISystemMessengerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} + if err != nil { + return *new(common.Address), err + } -// ISystemMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. -type ISystemMessengerRaw struct { - Contract *ISystemMessenger // Generic contract binding to access the raw methods on -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err -// ISystemMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type ISystemMessengerCallerRaw struct { - Contract *ISystemMessengerCaller // Generic read-only contract binding to access the raw methods on } -// ISystemMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type ISystemMessengerTransactorRaw struct { - Contract *ISystemMessengerTransactor // Generic write-only contract binding to access the raw methods on +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeSession) Owner() (common.Address, error) { + return _Home.Contract.Owner(&_Home.CallOpts) } -// NewISystemMessenger creates a new instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessenger(address common.Address, backend bind.ContractBackend) (*ISystemMessenger, error) { - contract, err := bindISystemMessenger(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &ISystemMessenger{ISystemMessengerCaller: ISystemMessengerCaller{contract: contract}, ISystemMessengerTransactor: ISystemMessengerTransactor{contract: contract}, ISystemMessengerFilterer: ISystemMessengerFilterer{contract: contract}}, nil +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_Home *HomeCallerSession) Owner() (common.Address, error) { + return _Home.Contract.Owner(&_Home.CallOpts) } -// NewISystemMessengerCaller creates a new read-only instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerCaller(address common.Address, caller bind.ContractCaller) (*ISystemMessengerCaller, error) { - contract, err := bindISystemMessenger(address, caller, nil, nil) +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeCaller) Root(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "root") + if err != nil { - return nil, err + return *new([32]byte), err } - return &ISystemMessengerCaller{contract: contract}, nil + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + } -// NewISystemMessengerTransactor creates a new write-only instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*ISystemMessengerTransactor, error) { - contract, err := bindISystemMessenger(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &ISystemMessengerTransactor{contract: contract}, nil +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeSession) Root() ([32]byte, error) { + return _Home.Contract.Root(&_Home.CallOpts) } -// NewISystemMessengerFilterer creates a new log filterer instance of ISystemMessenger, bound to a specific deployed contract. -func NewISystemMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*ISystemMessengerFilterer, error) { - contract, err := bindISystemMessenger(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &ISystemMessengerFilterer{contract: contract}, nil +// Root is a free data retrieval call binding the contract method 0xebf0c717. +// +// Solidity: function root() view returns(bytes32) +func (_Home *HomeCallerSession) Root() ([32]byte, error) { + return _Home.Contract.Root(&_Home.CallOpts) } -// bindISystemMessenger binds a generic wrapper to an already deployed contract. -func bindISystemMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(ISystemMessengerABI)) +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeCaller) State(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "state") + if err != nil { - return nil, err + return *new(uint8), err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil -} -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ISystemMessenger *ISystemMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ISystemMessenger.Contract.ISystemMessengerCaller.contract.Call(opts, result, method, params...) -} + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ISystemMessenger *ISystemMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transfer(opts) -} + return out0, err -// Transact invokes the (paid) contract method with params as input values. -func (_ISystemMessenger *ISystemMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transact(opts, method, params...) } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_ISystemMessenger *ISystemMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _ISystemMessenger.Contract.contract.Call(opts, result, method, params...) +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeSession) State() (uint8, error) { + return _Home.Contract.State(&_Home.CallOpts) } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _ISystemMessenger.Contract.contract.Transfer(opts) +// State is a free data retrieval call binding the contract method 0xc19d93fb. +// +// Solidity: function state() view returns(uint8) +func (_Home *HomeCallerSession) State() (uint8, error) { + return _Home.Contract.State(&_Home.CallOpts) } -// Transact invokes the (paid) contract method with params as input values. -func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _ISystemMessenger.Contract.contract.Transact(opts, method, params...) +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. +// +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeCaller) SuggestUpdate(opts *bind.CallOpts) (struct { + Nonce uint32 + Root [32]byte +}, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "suggestUpdate") + + outstruct := new(struct { + Nonce uint32 + Root [32]byte + }) + if err != nil { + return *outstruct, err + } + + outstruct.Nonce = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.Root = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + + return *outstruct, err + } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerTransactor) SendSystemMessage(opts *bind.TransactOpts, _destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.contract.Transact(opts, "sendSystemMessage", _destDomain, _recipient, _payload) +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeSession) SuggestUpdate() (struct { + Nonce uint32 + Root [32]byte +}, error) { + return _Home.Contract.SuggestUpdate(&_Home.CallOpts) } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// SuggestUpdate is a free data retrieval call binding the contract method 0x36e104de. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) +// Solidity: function suggestUpdate() view returns(uint32 _nonce, bytes32 _root) +func (_Home *HomeCallerSession) SuggestUpdate() (struct { + Nonce uint32 + Root [32]byte +}, error) { + return _Home.Contract.SuggestUpdate(&_Home.CallOpts) } -// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. // -// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() -func (_ISystemMessenger *ISystemMessengerTransactorSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { - return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) -} +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "systemMessenger") -// IUpdaterManagerMetaData contains all meta data concerning the IUpdaterManager contract. -var IUpdaterManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "5b3c2cbf": "slashUpdater(address)", - "df034cd0": "updater()", - }, -} + if err != nil { + return *new(common.Address), err + } -// IUpdaterManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use IUpdaterManagerMetaData.ABI instead. -var IUpdaterManagerABI = IUpdaterManagerMetaData.ABI + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) -// Deprecated: Use IUpdaterManagerMetaData.Sigs instead. -// IUpdaterManagerFuncSigs maps the 4-byte function signature to its string representation. -var IUpdaterManagerFuncSigs = IUpdaterManagerMetaData.Sigs + return out0, err -// IUpdaterManager is an auto generated Go binding around an Ethereum contract. -type IUpdaterManager struct { - IUpdaterManagerCaller // Read-only binding to the contract - IUpdaterManagerTransactor // Write-only binding to the contract - IUpdaterManagerFilterer // Log filterer for contract events } -// IUpdaterManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type IUpdaterManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeSession) SystemMessenger() (common.Address, error) { + return _Home.Contract.SystemMessenger(&_Home.CallOpts) } -// IUpdaterManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type IUpdaterManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_Home *HomeCallerSession) SystemMessenger() (common.Address, error) { + return _Home.Contract.SystemMessenger(&_Home.CallOpts) } -// IUpdaterManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type IUpdaterManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "tree") -// IUpdaterManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type IUpdaterManagerSession struct { - Contract *IUpdaterManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} + if err != nil { + return *new(*big.Int), err + } -// IUpdaterManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type IUpdaterManagerCallerSession struct { - Contract *IUpdaterManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) -// IUpdaterManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type IUpdaterManagerTransactorSession struct { - Contract *IUpdaterManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} + return out0, err -// IUpdaterManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type IUpdaterManagerRaw struct { - Contract *IUpdaterManager // Generic contract binding to access the raw methods on } -// IUpdaterManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type IUpdaterManagerCallerRaw struct { - Contract *IUpdaterManagerCaller // Generic read-only contract binding to access the raw methods on +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeSession) Tree() (*big.Int, error) { + return _Home.Contract.Tree(&_Home.CallOpts) } -// IUpdaterManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type IUpdaterManagerTransactorRaw struct { - Contract *IUpdaterManagerTransactor // Generic write-only contract binding to access the raw methods on +// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// +// Solidity: function tree() view returns(uint256 count) +func (_Home *HomeCallerSession) Tree() (*big.Int, error) { + return _Home.Contract.Tree(&_Home.CallOpts) } -// NewIUpdaterManager creates a new instance of IUpdaterManager, bound to a specific deployed contract. -func NewIUpdaterManager(address common.Address, backend bind.ContractBackend) (*IUpdaterManager, error) { - contract, err := bindIUpdaterManager(address, backend, backend, backend) +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeCaller) UpdaterManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Home.contract.Call(opts, &out, "updaterManager") + if err != nil { - return nil, err + return *new(common.Address), err } - return &IUpdaterManager{IUpdaterManagerCaller: IUpdaterManagerCaller{contract: contract}, IUpdaterManagerTransactor: IUpdaterManagerTransactor{contract: contract}, IUpdaterManagerFilterer: IUpdaterManagerFilterer{contract: contract}}, nil -} -// NewIUpdaterManagerCaller creates a new read-only instance of IUpdaterManager, bound to a specific deployed contract. -func NewIUpdaterManagerCaller(address common.Address, caller bind.ContractCaller) (*IUpdaterManagerCaller, error) { - contract, err := bindIUpdaterManager(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &IUpdaterManagerCaller{contract: contract}, nil -} + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) -// NewIUpdaterManagerTransactor creates a new write-only instance of IUpdaterManager, bound to a specific deployed contract. -func NewIUpdaterManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*IUpdaterManagerTransactor, error) { - contract, err := bindIUpdaterManager(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &IUpdaterManagerTransactor{contract: contract}, nil -} + return out0, err -// NewIUpdaterManagerFilterer creates a new log filterer instance of IUpdaterManager, bound to a specific deployed contract. -func NewIUpdaterManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*IUpdaterManagerFilterer, error) { - contract, err := bindIUpdaterManager(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &IUpdaterManagerFilterer{contract: contract}, nil } -// bindIUpdaterManager binds a generic wrapper to an already deployed contract. -func bindIUpdaterManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(IUpdaterManagerABI)) - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeSession) UpdaterManager() (common.Address, error) { + return _Home.Contract.UpdaterManager(&_Home.CallOpts) } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_IUpdaterManager *IUpdaterManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IUpdaterManager.Contract.IUpdaterManagerCaller.contract.Call(opts, result, method, params...) +// UpdaterManager is a free data retrieval call binding the contract method 0x9df6c8e1. +// +// Solidity: function updaterManager() view returns(address) +func (_Home *HomeCallerSession) UpdaterManager() (common.Address, error) { + return _Home.Contract.UpdaterManager(&_Home.CallOpts) } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_IUpdaterManager *IUpdaterManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IUpdaterManager.Contract.IUpdaterManagerTransactor.contract.Transfer(opts) +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeTransactor) Dispatch(opts *bind.TransactOpts, _destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "dispatch", _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) } -// Transact invokes the (paid) contract method with params as input values. -func (_IUpdaterManager *IUpdaterManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IUpdaterManager.Contract.IUpdaterManagerTransactor.contract.Transact(opts, method, params...) +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_IUpdaterManager *IUpdaterManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _IUpdaterManager.Contract.contract.Call(opts, result, method, params...) +// Dispatch is a paid mutator transaction binding the contract method 0xf7560e40. +// +// Solidity: function dispatch(uint32 _destinationDomain, bytes32 _recipientAddress, uint32 _optimisticSeconds, bytes _tips, bytes _messageBody) payable returns() +func (_Home *HomeTransactorSession) Dispatch(_destinationDomain uint32, _recipientAddress [32]byte, _optimisticSeconds uint32, _tips []byte, _messageBody []byte) (*types.Transaction, error) { + return _Home.Contract.Dispatch(&_Home.TransactOpts, _destinationDomain, _recipientAddress, _optimisticSeconds, _tips, _messageBody) } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_IUpdaterManager *IUpdaterManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _IUpdaterManager.Contract.contract.Transfer(opts) +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeTransactor) ImproperAttestation(opts *bind.TransactOpts, _attestation []byte) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "improperAttestation", _attestation) } -// Transact invokes the (paid) contract method with params as input values. -func (_IUpdaterManager *IUpdaterManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _IUpdaterManager.Contract.contract.Transact(opts, method, params...) +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. +// +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { + return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. +// ImproperAttestation is a paid mutator transaction binding the contract method 0x0afe7f90. // -// Solidity: function updater() view returns(address) -func (_IUpdaterManager *IUpdaterManagerCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _IUpdaterManager.contract.Call(opts, &out, "updater") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +// Solidity: function improperAttestation(bytes _attestation) returns(bool) +func (_Home *HomeTransactorSession) ImproperAttestation(_attestation []byte) (*types.Transaction, error) { + return _Home.Contract.ImproperAttestation(&_Home.TransactOpts, _attestation) } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function updater() view returns(address) -func (_IUpdaterManager *IUpdaterManagerSession) Updater() (common.Address, error) { - return _IUpdaterManager.Contract.Updater(&_IUpdaterManager.CallOpts) +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeTransactor) Initialize(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "initialize", _updaterManager) } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function updater() view returns(address) -func (_IUpdaterManager *IUpdaterManagerCallerSession) Updater() (common.Address, error) { - return _IUpdaterManager.Contract.Updater(&_IUpdaterManager.CallOpts) +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) } -// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. // -// Solidity: function slashUpdater(address _reporter) returns() -func (_IUpdaterManager *IUpdaterManagerTransactor) SlashUpdater(opts *bind.TransactOpts, _reporter common.Address) (*types.Transaction, error) { - return _IUpdaterManager.contract.Transact(opts, "slashUpdater", _reporter) +// Solidity: function initialize(address _updaterManager) returns() +func (_Home *HomeTransactorSession) Initialize(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.Initialize(&_Home.TransactOpts, _updaterManager) } -// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function slashUpdater(address _reporter) returns() -func (_IUpdaterManager *IUpdaterManagerSession) SlashUpdater(_reporter common.Address) (*types.Transaction, error) { - return _IUpdaterManager.Contract.SlashUpdater(&_IUpdaterManager.TransactOpts, _reporter) +// Solidity: function renounceOwnership() returns() +func (_Home *HomeTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "renounceOwnership") } -// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // -// Solidity: function slashUpdater(address _reporter) returns() -func (_IUpdaterManager *IUpdaterManagerTransactorSession) SlashUpdater(_reporter common.Address) (*types.Transaction, error) { - return _IUpdaterManager.Contract.SlashUpdater(&_IUpdaterManager.TransactOpts, _reporter) +// Solidity: function renounceOwnership() returns() +func (_Home *HomeSession) RenounceOwnership() (*types.Transaction, error) { + return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) } -// InitializableMetaData contains all meta data concerning the Initializable contract. -var InitializableMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_Home *HomeTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _Home.Contract.RenounceOwnership(&_Home.TransactOpts) } -// InitializableABI is the input ABI used to generate the binding from. -// Deprecated: Use InitializableMetaData.ABI instead. -var InitializableABI = InitializableMetaData.ABI - -// Initializable is an auto generated Go binding around an Ethereum contract. -type Initializable struct { - InitializableCaller // Read-only binding to the contract - InitializableTransactor // Write-only binding to the contract - InitializableFilterer // Log filterer for contract events +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setSystemMessenger", _systemMessenger) } -// InitializableCaller is an auto generated read-only Go binding around an Ethereum contract. -type InitializableCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) } -// InitializableTransactor is an auto generated write-only Go binding around an Ethereum contract. -type InitializableTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_Home *HomeTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _Home.Contract.SetSystemMessenger(&_Home.TransactOpts, _systemMessenger) } -// InitializableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type InitializableFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeTransactor) SetUpdater(opts *bind.TransactOpts, _updater common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setUpdater", _updater) } -// InitializableSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type InitializableSession struct { - Contract *Initializable // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) } -// InitializableCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type InitializableCallerSession struct { - Contract *InitializableCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updater) returns() +func (_Home *HomeTransactorSession) SetUpdater(_updater common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdater(&_Home.TransactOpts, _updater) } -// InitializableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type InitializableTransactorSession struct { - Contract *InitializableTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeTransactor) SetUpdaterManager(opts *bind.TransactOpts, _updaterManager common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "setUpdaterManager", _updaterManager) } -// InitializableRaw is an auto generated low-level Go binding around an Ethereum contract. -type InitializableRaw struct { - Contract *Initializable // Generic contract binding to access the raw methods on +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) } -// InitializableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type InitializableCallerRaw struct { - Contract *InitializableCaller // Generic read-only contract binding to access the raw methods on +// SetUpdaterManager is a paid mutator transaction binding the contract method 0x9776120e. +// +// Solidity: function setUpdaterManager(address _updaterManager) returns() +func (_Home *HomeTransactorSession) SetUpdaterManager(_updaterManager common.Address) (*types.Transaction, error) { + return _Home.Contract.SetUpdaterManager(&_Home.TransactOpts, _updaterManager) } -// InitializableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type InitializableTransactorRaw struct { - Contract *InitializableTransactor // Generic write-only contract binding to access the raw methods on +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Home.contract.Transact(opts, "transferOwnership", newOwner) } -// NewInitializable creates a new instance of Initializable, bound to a specific deployed contract. -func NewInitializable(address common.Address, backend bind.ContractBackend) (*Initializable, error) { - contract, err := bindInitializable(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &Initializable{InitializableCaller: InitializableCaller{contract: contract}, InitializableTransactor: InitializableTransactor{contract: contract}, InitializableFilterer: InitializableFilterer{contract: contract}}, nil +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) } -// NewInitializableCaller creates a new read-only instance of Initializable, bound to a specific deployed contract. -func NewInitializableCaller(address common.Address, caller bind.ContractCaller) (*InitializableCaller, error) { - contract, err := bindInitializable(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &InitializableCaller{contract: contract}, nil +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_Home *HomeTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Home.Contract.TransferOwnership(&_Home.TransactOpts, newOwner) } -// NewInitializableTransactor creates a new write-only instance of Initializable, bound to a specific deployed contract. -func NewInitializableTransactor(address common.Address, transactor bind.ContractTransactor) (*InitializableTransactor, error) { - contract, err := bindInitializable(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &InitializableTransactor{contract: contract}, nil +// HomeDispatchIterator is returned from FilterDispatch and is used to iterate over the raw logs and unpacked data for Dispatch events raised by the Home contract. +type HomeDispatchIterator struct { + Event *HomeDispatch // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// NewInitializableFilterer creates a new log filterer instance of Initializable, bound to a specific deployed contract. -func NewInitializableFilterer(address common.Address, filterer bind.ContractFilterer) (*InitializableFilterer, error) { - contract, err := bindInitializable(address, nil, nil, filterer) - if err != nil { - return nil, err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeDispatchIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } - return &InitializableFilterer{contract: contract}, nil -} + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeDispatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// bindInitializable binds a generic wrapper to an already deployed contract. -func bindInitializable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(InitializableABI)) - if err != nil { - return nil, err + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeDispatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Initializable *InitializableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Initializable.Contract.InitializableCaller.contract.Call(opts, result, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeDispatchIterator) Error() error { + return it.fail } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Initializable *InitializableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Initializable.Contract.InitializableTransactor.contract.Transfer(opts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeDispatchIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transact invokes the (paid) contract method with params as input values. -func (_Initializable *InitializableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Initializable.Contract.InitializableTransactor.contract.Transact(opts, method, params...) +// HomeDispatch represents a Dispatch event raised by the Home contract. +type HomeDispatch struct { + MessageHash [32]byte + LeafIndex *big.Int + DestinationAndNonce uint64 + Tips []byte + Message []byte + Raw types.Log // Blockchain specific contextual infos } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Initializable *InitializableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Initializable.Contract.contract.Call(opts, result, method, params...) +// FilterDispatch is a free log retrieval operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) FilterDispatch(opts *bind.FilterOpts, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (*HomeDispatchIterator, error) { + + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) + } + var leafIndexRule []interface{} + for _, leafIndexItem := range leafIndex { + leafIndexRule = append(leafIndexRule, leafIndexItem) + } + var destinationAndNonceRule []interface{} + for _, destinationAndNonceItem := range destinationAndNonce { + destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) + } + + logs, sub, err := _Home.contract.FilterLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + if err != nil { + return nil, err + } + return &HomeDispatchIterator{contract: _Home.contract, event: "Dispatch", logs: logs, sub: sub}, nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Initializable *InitializableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Initializable.Contract.contract.Transfer(opts) +// WatchDispatch is a free log subscription operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) WatchDispatch(opts *bind.WatchOpts, sink chan<- *HomeDispatch, messageHash [][32]byte, leafIndex []*big.Int, destinationAndNonce []uint64) (event.Subscription, error) { + + var messageHashRule []interface{} + for _, messageHashItem := range messageHash { + messageHashRule = append(messageHashRule, messageHashItem) + } + var leafIndexRule []interface{} + for _, leafIndexItem := range leafIndex { + leafIndexRule = append(leafIndexRule, leafIndexItem) + } + var destinationAndNonceRule []interface{} + for _, destinationAndNonceItem := range destinationAndNonce { + destinationAndNonceRule = append(destinationAndNonceRule, destinationAndNonceItem) + } + + logs, sub, err := _Home.contract.WatchLogs(opts, "Dispatch", messageHashRule, leafIndexRule, destinationAndNonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeDispatch) + if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// Transact invokes the (paid) contract method with params as input values. -func (_Initializable *InitializableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Initializable.Contract.contract.Transact(opts, method, params...) +// ParseDispatch is a log parse operation binding the contract event 0x718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e785. +// +// Solidity: event Dispatch(bytes32 indexed messageHash, uint256 indexed leafIndex, uint64 indexed destinationAndNonce, bytes tips, bytes message) +func (_Home *HomeFilterer) ParseDispatch(log types.Log) (*HomeDispatch, error) { + event := new(HomeDispatch) + if err := _Home.contract.UnpackLog(event, "Dispatch", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// InitializableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Initializable contract. -type InitializableInitializedIterator struct { - Event *InitializableInitialized // Event containing the contract specifics and raw log +// HomeDomainNotaryAddedIterator is returned from FilterDomainNotaryAdded and is used to iterate over the raw logs and unpacked data for DomainNotaryAdded events raised by the Home contract. +type HomeDomainNotaryAddedIterator struct { + Event *HomeDomainNotaryAdded // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -4198,7 +4220,7 @@ type InitializableInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *InitializableInitializedIterator) Next() bool { +func (it *HomeDomainNotaryAddedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -4207,7 +4229,7 @@ func (it *InitializableInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(InitializableInitialized) + it.Event = new(HomeDomainNotaryAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4222,7 +4244,7 @@ func (it *InitializableInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(InitializableInitialized) + it.Event = new(HomeDomainNotaryAdded) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -4238,41 +4260,41 @@ func (it *InitializableInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *InitializableInitializedIterator) Error() error { +func (it *HomeDomainNotaryAddedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *InitializableInitializedIterator) Close() error { +func (it *HomeDomainNotaryAddedIterator) Close() error { it.sub.Unsubscribe() return nil } -// InitializableInitialized represents a Initialized event raised by the Initializable contract. -type InitializableInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// HomeDomainNotaryAdded represents a DomainNotaryAdded event raised by the Home contract. +type HomeDomainNotaryAdded struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterDomainNotaryAdded is a free log retrieval operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) FilterInitialized(opts *bind.FilterOpts) (*InitializableInitializedIterator, error) { +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) FilterDomainNotaryAdded(opts *bind.FilterOpts) (*HomeDomainNotaryAddedIterator, error) { - logs, sub, err := _Initializable.contract.FilterLogs(opts, "Initialized") + logs, sub, err := _Home.contract.FilterLogs(opts, "DomainNotaryAdded") if err != nil { return nil, err } - return &InitializableInitializedIterator{contract: _Initializable.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &HomeDomainNotaryAddedIterator{contract: _Home.contract, event: "DomainNotaryAdded", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchDomainNotaryAdded is a free log subscription operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *InitializableInitialized) (event.Subscription, error) { +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) WatchDomainNotaryAdded(opts *bind.WatchOpts, sink chan<- *HomeDomainNotaryAdded) (event.Subscription, error) { - logs, sub, err := _Initializable.contract.WatchLogs(opts, "Initialized") + logs, sub, err := _Home.contract.WatchLogs(opts, "DomainNotaryAdded") if err != nil { return nil, err } @@ -4282,8 +4304,8 @@ func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOp select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(InitializableInitialized) - if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(HomeDomainNotaryAdded) + if err := _Home.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { return err } event.Raw = log @@ -4304,330 +4326,1423 @@ func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOp }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseDomainNotaryAdded is a log parse operation binding the contract event 0x7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd1. // -// Solidity: event Initialized(uint8 version) -func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*InitializableInitialized, error) { - event := new(InitializableInitialized) - if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event DomainNotaryAdded(address notary) +func (_Home *HomeFilterer) ParseDomainNotaryAdded(log types.Log) (*HomeDomainNotaryAdded, error) { + event := new(HomeDomainNotaryAdded) + if err := _Home.contract.UnpackLog(event, "DomainNotaryAdded", log); err != nil { return nil, err } event.Raw = log return event, nil } -// MerkleLibMetaData contains all meta data concerning the MerkleLib contract. -var MerkleLibMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122053b404cb801ab494745e26639a91af69ae049f0725ba055f234476db3559a1e264736f6c634300080d0033", -} - -// MerkleLibABI is the input ABI used to generate the binding from. -// Deprecated: Use MerkleLibMetaData.ABI instead. -var MerkleLibABI = MerkleLibMetaData.ABI +// HomeDomainNotaryRemovedIterator is returned from FilterDomainNotaryRemoved and is used to iterate over the raw logs and unpacked data for DomainNotaryRemoved events raised by the Home contract. +type HomeDomainNotaryRemovedIterator struct { + Event *HomeDomainNotaryRemoved // Event containing the contract specifics and raw log -// MerkleLibBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use MerkleLibMetaData.Bin instead. -var MerkleLibBin = MerkleLibMetaData.Bin + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// DeployMerkleLib deploys a new Ethereum contract, binding an instance of MerkleLib to it. -func DeployMerkleLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MerkleLib, error) { - parsed, err := MerkleLibMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeDomainNotaryRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeDomainNotaryRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MerkleLibBin), backend) - if err != nil { - return common.Address{}, nil, nil, err + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() } - return address, tx, &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil } -// MerkleLib is an auto generated Go binding around an Ethereum contract. -type MerkleLib struct { - MerkleLibCaller // Read-only binding to the contract - MerkleLibTransactor // Write-only binding to the contract - MerkleLibFilterer // Log filterer for contract events +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeDomainNotaryRemovedIterator) Error() error { + return it.fail } -// MerkleLibCaller is an auto generated read-only Go binding around an Ethereum contract. -type MerkleLibCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeDomainNotaryRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// MerkleLibTransactor is an auto generated write-only Go binding around an Ethereum contract. -type MerkleLibTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// HomeDomainNotaryRemoved represents a DomainNotaryRemoved event raised by the Home contract. +type HomeDomainNotaryRemoved struct { + Notary common.Address + Raw types.Log // Blockchain specific contextual infos } -// MerkleLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type MerkleLibFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} +// FilterDomainNotaryRemoved is a free log retrieval operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) FilterDomainNotaryRemoved(opts *bind.FilterOpts) (*HomeDomainNotaryRemovedIterator, error) { -// MerkleLibSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type MerkleLibSession struct { - Contract *MerkleLib // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + logs, sub, err := _Home.contract.FilterLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return &HomeDomainNotaryRemovedIterator{contract: _Home.contract, event: "DomainNotaryRemoved", logs: logs, sub: sub}, nil } -// MerkleLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type MerkleLibCallerSession struct { - Contract *MerkleLibCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +// WatchDomainNotaryRemoved is a free log subscription operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) WatchDomainNotaryRemoved(opts *bind.WatchOpts, sink chan<- *HomeDomainNotaryRemoved) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "DomainNotaryRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeDomainNotaryRemoved) + if err := _Home.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// MerkleLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type MerkleLibTransactorSession struct { - Contract *MerkleLibTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// ParseDomainNotaryRemoved is a log parse operation binding the contract event 0xe16811bec5badeb0bade36ad31aab1c20f2997b625833474449f893eeecd3bac. +// +// Solidity: event DomainNotaryRemoved(address notary) +func (_Home *HomeFilterer) ParseDomainNotaryRemoved(log types.Log) (*HomeDomainNotaryRemoved, error) { + event := new(HomeDomainNotaryRemoved) + if err := _Home.contract.UnpackLog(event, "DomainNotaryRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// MerkleLibRaw is an auto generated low-level Go binding around an Ethereum contract. -type MerkleLibRaw struct { - Contract *MerkleLib // Generic contract binding to access the raw methods on +// HomeGuardAddedIterator is returned from FilterGuardAdded and is used to iterate over the raw logs and unpacked data for GuardAdded events raised by the Home contract. +type HomeGuardAddedIterator struct { + Event *HomeGuardAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// MerkleLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type MerkleLibCallerRaw struct { - Contract *MerkleLibCaller // Generic read-only contract binding to access the raw methods on +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeGuardAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeGuardAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// MerkleLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type MerkleLibTransactorRaw struct { - Contract *MerkleLibTransactor // Generic write-only contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeGuardAddedIterator) Error() error { + return it.fail } -// NewMerkleLib creates a new instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLib(address common.Address, backend bind.ContractBackend) (*MerkleLib, error) { - contract, err := bindMerkleLib(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeGuardAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// NewMerkleLibCaller creates a new read-only instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibCaller(address common.Address, caller bind.ContractCaller) (*MerkleLibCaller, error) { - contract, err := bindMerkleLib(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &MerkleLibCaller{contract: contract}, nil +// HomeGuardAdded represents a GuardAdded event raised by the Home contract. +type HomeGuardAdded struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos } -// NewMerkleLibTransactor creates a new write-only instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibTransactor(address common.Address, transactor bind.ContractTransactor) (*MerkleLibTransactor, error) { - contract, err := bindMerkleLib(address, nil, transactor, nil) +// FilterGuardAdded is a free log retrieval operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) FilterGuardAdded(opts *bind.FilterOpts) (*HomeGuardAddedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "GuardAdded") if err != nil { return nil, err } - return &MerkleLibTransactor{contract: contract}, nil + return &HomeGuardAddedIterator{contract: _Home.contract, event: "GuardAdded", logs: logs, sub: sub}, nil } -// NewMerkleLibFilterer creates a new log filterer instance of MerkleLib, bound to a specific deployed contract. -func NewMerkleLibFilterer(address common.Address, filterer bind.ContractFilterer) (*MerkleLibFilterer, error) { - contract, err := bindMerkleLib(address, nil, nil, filterer) +// WatchGuardAdded is a free log subscription operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) WatchGuardAdded(opts *bind.WatchOpts, sink chan<- *HomeGuardAdded) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "GuardAdded") if err != nil { return nil, err } - return &MerkleLibFilterer{contract: contract}, nil + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeGuardAdded) + if err := _Home.contract.UnpackLog(event, "GuardAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// bindMerkleLib binds a generic wrapper to an already deployed contract. -func bindMerkleLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(MerkleLibABI)) - if err != nil { +// ParseGuardAdded is a log parse operation binding the contract event 0x93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f59. +// +// Solidity: event GuardAdded(address guard) +func (_Home *HomeFilterer) ParseGuardAdded(log types.Log) (*HomeGuardAdded, error) { + event := new(HomeGuardAdded) + if err := _Home.contract.UnpackLog(event, "GuardAdded", log); err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + event.Raw = log + return event, nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_MerkleLib *MerkleLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MerkleLib.Contract.MerkleLibCaller.contract.Call(opts, result, method, params...) -} +// HomeGuardRemovedIterator is returned from FilterGuardRemoved and is used to iterate over the raw logs and unpacked data for GuardRemoved events raised by the Home contract. +type HomeGuardRemovedIterator struct { + Event *HomeGuardRemoved // Event containing the contract specifics and raw log -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_MerkleLib *MerkleLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MerkleLib.Contract.MerkleLibTransactor.contract.Transfer(opts) -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// Transact invokes the (paid) contract method with params as input values. -func (_MerkleLib *MerkleLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MerkleLib.Contract.MerkleLibTransactor.contract.Transact(opts, method, params...) + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_MerkleLib *MerkleLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MerkleLib.Contract.contract.Call(opts, result, method, params...) -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeGuardRemovedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_MerkleLib *MerkleLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MerkleLib.Contract.contract.Transfer(opts) -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeGuardRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// Transact invokes the (paid) contract method with params as input values. -func (_MerkleLib *MerkleLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MerkleLib.Contract.contract.Transact(opts, method, params...) + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// MerkleTreeManagerMetaData contains all meta data concerning the MerkleTreeManager contract. -var MerkleTreeManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "06661abd": "count()", - "7ea97f40": "historicalRoots(uint256)", - "ebf0c717": "root()", - "fd54b228": "tree()", - }, - Bin: "0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212201a04f9fd6ec545477fca6f1cb2ff2a3834f1eb10850e7a9fc0772460433bada964736f6c634300080d0033", +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeGuardRemovedIterator) Error() error { + return it.fail } -// MerkleTreeManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use MerkleTreeManagerMetaData.ABI instead. -var MerkleTreeManagerABI = MerkleTreeManagerMetaData.ABI +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeGuardRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} -// Deprecated: Use MerkleTreeManagerMetaData.Sigs instead. -// MerkleTreeManagerFuncSigs maps the 4-byte function signature to its string representation. -var MerkleTreeManagerFuncSigs = MerkleTreeManagerMetaData.Sigs +// HomeGuardRemoved represents a GuardRemoved event raised by the Home contract. +type HomeGuardRemoved struct { + Guard common.Address + Raw types.Log // Blockchain specific contextual infos +} -// MerkleTreeManagerBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use MerkleTreeManagerMetaData.Bin instead. -var MerkleTreeManagerBin = MerkleTreeManagerMetaData.Bin +// FilterGuardRemoved is a free log retrieval operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) FilterGuardRemoved(opts *bind.FilterOpts) (*HomeGuardRemovedIterator, error) { -// DeployMerkleTreeManager deploys a new Ethereum contract, binding an instance of MerkleTreeManager to it. -func DeployMerkleTreeManager(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MerkleTreeManager, error) { - parsed, err := MerkleTreeManagerMetaData.GetAbi() + logs, sub, err := _Home.contract.FilterLogs(opts, "GuardRemoved") if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + return nil, err } + return &HomeGuardRemovedIterator{contract: _Home.contract, event: "GuardRemoved", logs: logs, sub: sub}, nil +} - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MerkleTreeManagerBin), backend) +// WatchGuardRemoved is a free log subscription operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) WatchGuardRemoved(opts *bind.WatchOpts, sink chan<- *HomeGuardRemoved) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "GuardRemoved") if err != nil { - return common.Address{}, nil, nil, err + return nil, err } - return address, tx, &MerkleTreeManager{MerkleTreeManagerCaller: MerkleTreeManagerCaller{contract: contract}, MerkleTreeManagerTransactor: MerkleTreeManagerTransactor{contract: contract}, MerkleTreeManagerFilterer: MerkleTreeManagerFilterer{contract: contract}}, nil -} + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeGuardRemoved) + if err := _Home.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return err + } + event.Raw = log -// MerkleTreeManager is an auto generated Go binding around an Ethereum contract. -type MerkleTreeManager struct { - MerkleTreeManagerCaller // Read-only binding to the contract - MerkleTreeManagerTransactor // Write-only binding to the contract - MerkleTreeManagerFilterer // Log filterer for contract events + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// MerkleTreeManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type MerkleTreeManagerCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// ParseGuardRemoved is a log parse operation binding the contract event 0x59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d048. +// +// Solidity: event GuardRemoved(address guard) +func (_Home *HomeFilterer) ParseGuardRemoved(log types.Log) (*HomeGuardRemoved, error) { + event := new(HomeGuardRemoved) + if err := _Home.contract.UnpackLog(event, "GuardRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// MerkleTreeManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type MerkleTreeManagerTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} +// HomeImproperAttestationIterator is returned from FilterImproperAttestation and is used to iterate over the raw logs and unpacked data for ImproperAttestation events raised by the Home contract. +type HomeImproperAttestationIterator struct { + Event *HomeImproperAttestation // Event containing the contract specifics and raw log -// MerkleTreeManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type MerkleTreeManagerFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls -} + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data -// MerkleTreeManagerSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type MerkleTreeManagerSession struct { - Contract *MerkleTreeManager // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// MerkleTreeManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type MerkleTreeManagerCallerSession struct { - Contract *MerkleTreeManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeImproperAttestationIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeImproperAttestation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// MerkleTreeManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type MerkleTreeManagerTransactorSession struct { - Contract *MerkleTreeManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeImproperAttestation) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// MerkleTreeManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type MerkleTreeManagerRaw struct { - Contract *MerkleTreeManager // Generic contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeImproperAttestationIterator) Error() error { + return it.fail } -// MerkleTreeManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type MerkleTreeManagerCallerRaw struct { - Contract *MerkleTreeManagerCaller // Generic read-only contract binding to access the raw methods on +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeImproperAttestationIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// MerkleTreeManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type MerkleTreeManagerTransactorRaw struct { - Contract *MerkleTreeManagerTransactor // Generic write-only contract binding to access the raw methods on +// HomeImproperAttestation represents a ImproperAttestation event raised by the Home contract. +type HomeImproperAttestation struct { + Updater common.Address + Attestation []byte + Raw types.Log // Blockchain specific contextual infos } -// NewMerkleTreeManager creates a new instance of MerkleTreeManager, bound to a specific deployed contract. -func NewMerkleTreeManager(address common.Address, backend bind.ContractBackend) (*MerkleTreeManager, error) { - contract, err := bindMerkleTreeManager(address, backend, backend, backend) +// FilterImproperAttestation is a free log retrieval operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) FilterImproperAttestation(opts *bind.FilterOpts) (*HomeImproperAttestationIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "ImproperAttestation") if err != nil { return nil, err } - return &MerkleTreeManager{MerkleTreeManagerCaller: MerkleTreeManagerCaller{contract: contract}, MerkleTreeManagerTransactor: MerkleTreeManagerTransactor{contract: contract}, MerkleTreeManagerFilterer: MerkleTreeManagerFilterer{contract: contract}}, nil + return &HomeImproperAttestationIterator{contract: _Home.contract, event: "ImproperAttestation", logs: logs, sub: sub}, nil } -// NewMerkleTreeManagerCaller creates a new read-only instance of MerkleTreeManager, bound to a specific deployed contract. -func NewMerkleTreeManagerCaller(address common.Address, caller bind.ContractCaller) (*MerkleTreeManagerCaller, error) { - contract, err := bindMerkleTreeManager(address, caller, nil, nil) +// WatchImproperAttestation is a free log subscription operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) WatchImproperAttestation(opts *bind.WatchOpts, sink chan<- *HomeImproperAttestation) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "ImproperAttestation") if err != nil { return nil, err } - return &MerkleTreeManagerCaller{contract: contract}, nil -} - -// NewMerkleTreeManagerTransactor creates a new write-only instance of MerkleTreeManager, bound to a specific deployed contract. -func NewMerkleTreeManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*MerkleTreeManagerTransactor, error) { - contract, err := bindMerkleTreeManager(address, nil, transactor, nil) + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeImproperAttestation) + if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseImproperAttestation is a log parse operation binding the contract event 0x287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b. +// +// Solidity: event ImproperAttestation(address updater, bytes attestation) +func (_Home *HomeFilterer) ParseImproperAttestation(log types.Log) (*HomeImproperAttestation, error) { + event := new(HomeImproperAttestation) + if err := _Home.contract.UnpackLog(event, "ImproperAttestation", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Home contract. +type HomeInitializedIterator struct { + Event *HomeInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeInitialized represents a Initialized event raised by the Home contract. +type HomeInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) FilterInitialized(opts *bind.FilterOpts) (*HomeInitializedIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &HomeInitializedIterator{contract: _Home.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *HomeInitialized) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeInitialized) + if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Home *HomeFilterer) ParseInitialized(log types.Log) (*HomeInitialized, error) { + event := new(HomeInitialized) + if err := _Home.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeNewUpdaterManagerIterator is returned from FilterNewUpdaterManager and is used to iterate over the raw logs and unpacked data for NewUpdaterManager events raised by the Home contract. +type HomeNewUpdaterManagerIterator struct { + Event *HomeNewUpdaterManager // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeNewUpdaterManagerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeNewUpdaterManager) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeNewUpdaterManager) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeNewUpdaterManagerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeNewUpdaterManagerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeNewUpdaterManager represents a NewUpdaterManager event raised by the Home contract. +type HomeNewUpdaterManager struct { + UpdaterManager common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNewUpdaterManager is a free log retrieval operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) FilterNewUpdaterManager(opts *bind.FilterOpts) (*HomeNewUpdaterManagerIterator, error) { + + logs, sub, err := _Home.contract.FilterLogs(opts, "NewUpdaterManager") + if err != nil { + return nil, err + } + return &HomeNewUpdaterManagerIterator{contract: _Home.contract, event: "NewUpdaterManager", logs: logs, sub: sub}, nil +} + +// WatchNewUpdaterManager is a free log subscription operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) WatchNewUpdaterManager(opts *bind.WatchOpts, sink chan<- *HomeNewUpdaterManager) (event.Subscription, error) { + + logs, sub, err := _Home.contract.WatchLogs(opts, "NewUpdaterManager") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeNewUpdaterManager) + if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNewUpdaterManager is a log parse operation binding the contract event 0x958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf. +// +// Solidity: event NewUpdaterManager(address updaterManager) +func (_Home *HomeFilterer) ParseNewUpdaterManager(log types.Log) (*HomeNewUpdaterManager, error) { + event := new(HomeNewUpdaterManager) + if err := _Home.contract.UnpackLog(event, "NewUpdaterManager", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Home contract. +type HomeOwnershipTransferredIterator struct { + Event *HomeOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeOwnershipTransferred represents a OwnershipTransferred event raised by the Home contract. +type HomeOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*HomeOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Home.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &HomeOwnershipTransferredIterator{contract: _Home.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *HomeOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Home.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeOwnershipTransferred) + if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_Home *HomeFilterer) ParseOwnershipTransferred(log types.Log) (*HomeOwnershipTransferred, error) { + event := new(HomeOwnershipTransferred) + if err := _Home.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// HomeUpdaterSlashedIterator is returned from FilterUpdaterSlashed and is used to iterate over the raw logs and unpacked data for UpdaterSlashed events raised by the Home contract. +type HomeUpdaterSlashedIterator struct { + Event *HomeUpdaterSlashed // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *HomeUpdaterSlashedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(HomeUpdaterSlashed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(HomeUpdaterSlashed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *HomeUpdaterSlashedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *HomeUpdaterSlashedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// HomeUpdaterSlashed represents a UpdaterSlashed event raised by the Home contract. +type HomeUpdaterSlashed struct { + Updater common.Address + Reporter common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdaterSlashed is a free log retrieval operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// +// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) +func (_Home *HomeFilterer) FilterUpdaterSlashed(opts *bind.FilterOpts, updater []common.Address, reporter []common.Address) (*HomeUpdaterSlashedIterator, error) { + + var updaterRule []interface{} + for _, updaterItem := range updater { + updaterRule = append(updaterRule, updaterItem) + } + var reporterRule []interface{} + for _, reporterItem := range reporter { + reporterRule = append(reporterRule, reporterItem) + } + + logs, sub, err := _Home.contract.FilterLogs(opts, "UpdaterSlashed", updaterRule, reporterRule) + if err != nil { + return nil, err + } + return &HomeUpdaterSlashedIterator{contract: _Home.contract, event: "UpdaterSlashed", logs: logs, sub: sub}, nil +} + +// WatchUpdaterSlashed is a free log subscription operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// +// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) +func (_Home *HomeFilterer) WatchUpdaterSlashed(opts *bind.WatchOpts, sink chan<- *HomeUpdaterSlashed, updater []common.Address, reporter []common.Address) (event.Subscription, error) { + + var updaterRule []interface{} + for _, updaterItem := range updater { + updaterRule = append(updaterRule, updaterItem) + } + var reporterRule []interface{} + for _, reporterItem := range reporter { + reporterRule = append(reporterRule, reporterItem) + } + + logs, sub, err := _Home.contract.WatchLogs(opts, "UpdaterSlashed", updaterRule, reporterRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(HomeUpdaterSlashed) + if err := _Home.contract.UnpackLog(event, "UpdaterSlashed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdaterSlashed is a log parse operation binding the contract event 0x98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce. +// +// Solidity: event UpdaterSlashed(address indexed updater, address indexed reporter) +func (_Home *HomeFilterer) ParseUpdaterSlashed(log types.Log) (*HomeUpdaterSlashed, error) { + event := new(HomeUpdaterSlashed) + if err := _Home.contract.UnpackLog(event, "UpdaterSlashed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ISystemMessengerMetaData contains all meta data concerning the ISystemMessenger contract. +var ISystemMessengerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enumISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "0d1e27a7": "sendSystemMessage(uint32,uint8,bytes)", + }, +} + +// ISystemMessengerABI is the input ABI used to generate the binding from. +// Deprecated: Use ISystemMessengerMetaData.ABI instead. +var ISystemMessengerABI = ISystemMessengerMetaData.ABI + +// Deprecated: Use ISystemMessengerMetaData.Sigs instead. +// ISystemMessengerFuncSigs maps the 4-byte function signature to its string representation. +var ISystemMessengerFuncSigs = ISystemMessengerMetaData.Sigs + +// ISystemMessenger is an auto generated Go binding around an Ethereum contract. +type ISystemMessenger struct { + ISystemMessengerCaller // Read-only binding to the contract + ISystemMessengerTransactor // Write-only binding to the contract + ISystemMessengerFilterer // Log filterer for contract events +} + +// ISystemMessengerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ISystemMessengerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ISystemMessengerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ISystemMessengerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ISystemMessengerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ISystemMessengerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ISystemMessengerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ISystemMessengerSession struct { + Contract *ISystemMessenger // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ISystemMessengerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ISystemMessengerCallerSession struct { + Contract *ISystemMessengerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ISystemMessengerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ISystemMessengerTransactorSession struct { + Contract *ISystemMessengerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ISystemMessengerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ISystemMessengerRaw struct { + Contract *ISystemMessenger // Generic contract binding to access the raw methods on +} + +// ISystemMessengerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ISystemMessengerCallerRaw struct { + Contract *ISystemMessengerCaller // Generic read-only contract binding to access the raw methods on +} + +// ISystemMessengerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ISystemMessengerTransactorRaw struct { + Contract *ISystemMessengerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewISystemMessenger creates a new instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessenger(address common.Address, backend bind.ContractBackend) (*ISystemMessenger, error) { + contract, err := bindISystemMessenger(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ISystemMessenger{ISystemMessengerCaller: ISystemMessengerCaller{contract: contract}, ISystemMessengerTransactor: ISystemMessengerTransactor{contract: contract}, ISystemMessengerFilterer: ISystemMessengerFilterer{contract: contract}}, nil +} + +// NewISystemMessengerCaller creates a new read-only instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerCaller(address common.Address, caller bind.ContractCaller) (*ISystemMessengerCaller, error) { + contract, err := bindISystemMessenger(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ISystemMessengerCaller{contract: contract}, nil +} + +// NewISystemMessengerTransactor creates a new write-only instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerTransactor(address common.Address, transactor bind.ContractTransactor) (*ISystemMessengerTransactor, error) { + contract, err := bindISystemMessenger(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ISystemMessengerTransactor{contract: contract}, nil +} + +// NewISystemMessengerFilterer creates a new log filterer instance of ISystemMessenger, bound to a specific deployed contract. +func NewISystemMessengerFilterer(address common.Address, filterer bind.ContractFilterer) (*ISystemMessengerFilterer, error) { + contract, err := bindISystemMessenger(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ISystemMessengerFilterer{contract: contract}, nil +} + +// bindISystemMessenger binds a generic wrapper to an already deployed contract. +func bindISystemMessenger(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(ISystemMessengerABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ISystemMessenger *ISystemMessengerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ISystemMessenger.Contract.ISystemMessengerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ISystemMessenger *ISystemMessengerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ISystemMessenger *ISystemMessengerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ISystemMessenger.Contract.ISystemMessengerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ISystemMessenger *ISystemMessengerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ISystemMessenger.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ISystemMessenger.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ISystemMessenger *ISystemMessengerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ISystemMessenger.Contract.contract.Transact(opts, method, params...) +} + +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerTransactor) SendSystemMessage(opts *bind.TransactOpts, _destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.contract.Transact(opts, "sendSystemMessage", _destDomain, _recipient, _payload) +} + +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) +} + +// SendSystemMessage is a paid mutator transaction binding the contract method 0x0d1e27a7. +// +// Solidity: function sendSystemMessage(uint32 _destDomain, uint8 _recipient, bytes _payload) returns() +func (_ISystemMessenger *ISystemMessengerTransactorSession) SendSystemMessage(_destDomain uint32, _recipient uint8, _payload []byte) (*types.Transaction, error) { + return _ISystemMessenger.Contract.SendSystemMessage(&_ISystemMessenger.TransactOpts, _destDomain, _recipient, _payload) +} + +// IUpdaterManagerMetaData contains all meta data concerning the IUpdaterManager contract. +var IUpdaterManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "5b3c2cbf": "slashUpdater(address)", + "df034cd0": "updater()", + }, +} + +// IUpdaterManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use IUpdaterManagerMetaData.ABI instead. +var IUpdaterManagerABI = IUpdaterManagerMetaData.ABI + +// Deprecated: Use IUpdaterManagerMetaData.Sigs instead. +// IUpdaterManagerFuncSigs maps the 4-byte function signature to its string representation. +var IUpdaterManagerFuncSigs = IUpdaterManagerMetaData.Sigs + +// IUpdaterManager is an auto generated Go binding around an Ethereum contract. +type IUpdaterManager struct { + IUpdaterManagerCaller // Read-only binding to the contract + IUpdaterManagerTransactor // Write-only binding to the contract + IUpdaterManagerFilterer // Log filterer for contract events +} + +// IUpdaterManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type IUpdaterManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IUpdaterManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type IUpdaterManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IUpdaterManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IUpdaterManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IUpdaterManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IUpdaterManagerSession struct { + Contract *IUpdaterManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IUpdaterManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IUpdaterManagerCallerSession struct { + Contract *IUpdaterManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IUpdaterManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IUpdaterManagerTransactorSession struct { + Contract *IUpdaterManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IUpdaterManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type IUpdaterManagerRaw struct { + Contract *IUpdaterManager // Generic contract binding to access the raw methods on +} + +// IUpdaterManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IUpdaterManagerCallerRaw struct { + Contract *IUpdaterManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// IUpdaterManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IUpdaterManagerTransactorRaw struct { + Contract *IUpdaterManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewIUpdaterManager creates a new instance of IUpdaterManager, bound to a specific deployed contract. +func NewIUpdaterManager(address common.Address, backend bind.ContractBackend) (*IUpdaterManager, error) { + contract, err := bindIUpdaterManager(address, backend, backend, backend) if err != nil { return nil, err } - return &MerkleTreeManagerTransactor{contract: contract}, nil + return &IUpdaterManager{IUpdaterManagerCaller: IUpdaterManagerCaller{contract: contract}, IUpdaterManagerTransactor: IUpdaterManagerTransactor{contract: contract}, IUpdaterManagerFilterer: IUpdaterManagerFilterer{contract: contract}}, nil } -// NewMerkleTreeManagerFilterer creates a new log filterer instance of MerkleTreeManager, bound to a specific deployed contract. -func NewMerkleTreeManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*MerkleTreeManagerFilterer, error) { - contract, err := bindMerkleTreeManager(address, nil, nil, filterer) +// NewIUpdaterManagerCaller creates a new read-only instance of IUpdaterManager, bound to a specific deployed contract. +func NewIUpdaterManagerCaller(address common.Address, caller bind.ContractCaller) (*IUpdaterManagerCaller, error) { + contract, err := bindIUpdaterManager(address, caller, nil, nil) if err != nil { return nil, err } - return &MerkleTreeManagerFilterer{contract: contract}, nil + return &IUpdaterManagerCaller{contract: contract}, nil } -// bindMerkleTreeManager binds a generic wrapper to an already deployed contract. -func bindMerkleTreeManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(MerkleTreeManagerABI)) +// NewIUpdaterManagerTransactor creates a new write-only instance of IUpdaterManager, bound to a specific deployed contract. +func NewIUpdaterManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*IUpdaterManagerTransactor, error) { + contract, err := bindIUpdaterManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IUpdaterManagerTransactor{contract: contract}, nil +} + +// NewIUpdaterManagerFilterer creates a new log filterer instance of IUpdaterManager, bound to a specific deployed contract. +func NewIUpdaterManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*IUpdaterManagerFilterer, error) { + contract, err := bindIUpdaterManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IUpdaterManagerFilterer{contract: contract}, nil +} + +// bindIUpdaterManager binds a generic wrapper to an already deployed contract. +func bindIUpdaterManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(IUpdaterManagerABI)) if err != nil { return nil, err } @@ -4638,181 +5753,394 @@ func bindMerkleTreeManager(address common.Address, caller bind.ContractCaller, t // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MerkleTreeManager *MerkleTreeManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MerkleTreeManager.Contract.MerkleTreeManagerCaller.contract.Call(opts, result, method, params...) +func (_IUpdaterManager *IUpdaterManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IUpdaterManager.Contract.IUpdaterManagerCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_MerkleTreeManager *MerkleTreeManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MerkleTreeManager.Contract.MerkleTreeManagerTransactor.contract.Transfer(opts) +func (_IUpdaterManager *IUpdaterManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IUpdaterManager.Contract.IUpdaterManagerTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_MerkleTreeManager *MerkleTreeManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MerkleTreeManager.Contract.MerkleTreeManagerTransactor.contract.Transact(opts, method, params...) +func (_IUpdaterManager *IUpdaterManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IUpdaterManager.Contract.IUpdaterManagerTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_MerkleTreeManager *MerkleTreeManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _MerkleTreeManager.Contract.contract.Call(opts, result, method, params...) +func (_IUpdaterManager *IUpdaterManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IUpdaterManager.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_MerkleTreeManager *MerkleTreeManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _MerkleTreeManager.Contract.contract.Transfer(opts) +func (_IUpdaterManager *IUpdaterManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IUpdaterManager.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_MerkleTreeManager *MerkleTreeManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _MerkleTreeManager.Contract.contract.Transact(opts, method, params...) +func (_IUpdaterManager *IUpdaterManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IUpdaterManager.Contract.contract.Transact(opts, method, params...) } -// Count is a free data retrieval call binding the contract method 0x06661abd. +// Updater is a free data retrieval call binding the contract method 0xdf034cd0. // -// Solidity: function count() view returns(uint256) -func (_MerkleTreeManager *MerkleTreeManagerCaller) Count(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function updater() view returns(address) +func (_IUpdaterManager *IUpdaterManagerCaller) Updater(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _MerkleTreeManager.contract.Call(opts, &out, "count") + err := _IUpdaterManager.contract.Call(opts, &out, "updater") if err != nil { - return *new(*big.Int), err + return *new(common.Address), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) return out0, err } -// Count is a free data retrieval call binding the contract method 0x06661abd. +// Updater is a free data retrieval call binding the contract method 0xdf034cd0. // -// Solidity: function count() view returns(uint256) -func (_MerkleTreeManager *MerkleTreeManagerSession) Count() (*big.Int, error) { - return _MerkleTreeManager.Contract.Count(&_MerkleTreeManager.CallOpts) +// Solidity: function updater() view returns(address) +func (_IUpdaterManager *IUpdaterManagerSession) Updater() (common.Address, error) { + return _IUpdaterManager.Contract.Updater(&_IUpdaterManager.CallOpts) } -// Count is a free data retrieval call binding the contract method 0x06661abd. +// Updater is a free data retrieval call binding the contract method 0xdf034cd0. // -// Solidity: function count() view returns(uint256) -func (_MerkleTreeManager *MerkleTreeManagerCallerSession) Count() (*big.Int, error) { - return _MerkleTreeManager.Contract.Count(&_MerkleTreeManager.CallOpts) +// Solidity: function updater() view returns(address) +func (_IUpdaterManager *IUpdaterManagerCallerSession) Updater() (common.Address, error) { + return _IUpdaterManager.Contract.Updater(&_IUpdaterManager.CallOpts) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. +// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. // -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_MerkleTreeManager *MerkleTreeManagerCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { - var out []interface{} - err := _MerkleTreeManager.contract.Call(opts, &out, "historicalRoots", arg0) +// Solidity: function slashUpdater(address _reporter) returns() +func (_IUpdaterManager *IUpdaterManagerTransactor) SlashUpdater(opts *bind.TransactOpts, _reporter common.Address) (*types.Transaction, error) { + return _IUpdaterManager.contract.Transact(opts, "slashUpdater", _reporter) +} + +// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. +// +// Solidity: function slashUpdater(address _reporter) returns() +func (_IUpdaterManager *IUpdaterManagerSession) SlashUpdater(_reporter common.Address) (*types.Transaction, error) { + return _IUpdaterManager.Contract.SlashUpdater(&_IUpdaterManager.TransactOpts, _reporter) +} + +// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. +// +// Solidity: function slashUpdater(address _reporter) returns() +func (_IUpdaterManager *IUpdaterManagerTransactorSession) SlashUpdater(_reporter common.Address) (*types.Transaction, error) { + return _IUpdaterManager.Contract.SlashUpdater(&_IUpdaterManager.TransactOpts, _reporter) +} + +// InitializableMetaData contains all meta data concerning the Initializable contract. +var InitializableMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}]", +} + +// InitializableABI is the input ABI used to generate the binding from. +// Deprecated: Use InitializableMetaData.ABI instead. +var InitializableABI = InitializableMetaData.ABI + +// Initializable is an auto generated Go binding around an Ethereum contract. +type Initializable struct { + InitializableCaller // Read-only binding to the contract + InitializableTransactor // Write-only binding to the contract + InitializableFilterer // Log filterer for contract events +} + +// InitializableCaller is an auto generated read-only Go binding around an Ethereum contract. +type InitializableCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InitializableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type InitializableTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InitializableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type InitializableFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// InitializableSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type InitializableSession struct { + Contract *Initializable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InitializableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type InitializableCallerSession struct { + Contract *InitializableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// InitializableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type InitializableTransactorSession struct { + Contract *InitializableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// InitializableRaw is an auto generated low-level Go binding around an Ethereum contract. +type InitializableRaw struct { + Contract *Initializable // Generic contract binding to access the raw methods on +} + +// InitializableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type InitializableCallerRaw struct { + Contract *InitializableCaller // Generic read-only contract binding to access the raw methods on +} + +// InitializableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type InitializableTransactorRaw struct { + Contract *InitializableTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewInitializable creates a new instance of Initializable, bound to a specific deployed contract. +func NewInitializable(address common.Address, backend bind.ContractBackend) (*Initializable, error) { + contract, err := bindInitializable(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Initializable{InitializableCaller: InitializableCaller{contract: contract}, InitializableTransactor: InitializableTransactor{contract: contract}, InitializableFilterer: InitializableFilterer{contract: contract}}, nil +} +// NewInitializableCaller creates a new read-only instance of Initializable, bound to a specific deployed contract. +func NewInitializableCaller(address common.Address, caller bind.ContractCaller) (*InitializableCaller, error) { + contract, err := bindInitializable(address, caller, nil, nil) if err != nil { - return *new([32]byte), err + return nil, err } + return &InitializableCaller{contract: contract}, nil +} - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) +// NewInitializableTransactor creates a new write-only instance of Initializable, bound to a specific deployed contract. +func NewInitializableTransactor(address common.Address, transactor bind.ContractTransactor) (*InitializableTransactor, error) { + contract, err := bindInitializable(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &InitializableTransactor{contract: contract}, nil +} - return out0, err +// NewInitializableFilterer creates a new log filterer instance of Initializable, bound to a specific deployed contract. +func NewInitializableFilterer(address common.Address, filterer bind.ContractFilterer) (*InitializableFilterer, error) { + contract, err := bindInitializable(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &InitializableFilterer{contract: contract}, nil +} + +// bindInitializable binds a generic wrapper to an already deployed contract. +func bindInitializable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(InitializableABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Initializable *InitializableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Initializable.Contract.InitializableCaller.contract.Call(opts, result, method, params...) +} +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Initializable *InitializableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Initializable.Contract.InitializableTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Initializable *InitializableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Initializable.Contract.InitializableTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Initializable *InitializableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Initializable.Contract.contract.Call(opts, result, method, params...) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_MerkleTreeManager *MerkleTreeManagerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _MerkleTreeManager.Contract.HistoricalRoots(&_MerkleTreeManager.CallOpts, arg0) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Initializable *InitializableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Initializable.Contract.contract.Transfer(opts) } -// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. -// -// Solidity: function historicalRoots(uint256 ) view returns(bytes32) -func (_MerkleTreeManager *MerkleTreeManagerCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { - return _MerkleTreeManager.Contract.HistoricalRoots(&_MerkleTreeManager.CallOpts, arg0) +// Transact invokes the (paid) contract method with params as input values. +func (_Initializable *InitializableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Initializable.Contract.contract.Transact(opts, method, params...) } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_MerkleTreeManager *MerkleTreeManagerCaller) Root(opts *bind.CallOpts) ([32]byte, error) { - var out []interface{} - err := _MerkleTreeManager.contract.Call(opts, &out, "root") +// InitializableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Initializable contract. +type InitializableInitializedIterator struct { + Event *InitializableInitialized // Event containing the contract specifics and raw log - if err != nil { - return *new([32]byte), err + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *InitializableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(InitializableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(InitializableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true - return out0, err + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} +// Error returns any retrieval or parsing error occurred during filtering. +func (it *InitializableInitializedIterator) Error() error { + return it.fail } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_MerkleTreeManager *MerkleTreeManagerSession) Root() ([32]byte, error) { - return _MerkleTreeManager.Contract.Root(&_MerkleTreeManager.CallOpts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *InitializableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Root is a free data retrieval call binding the contract method 0xebf0c717. -// -// Solidity: function root() view returns(bytes32) -func (_MerkleTreeManager *MerkleTreeManagerCallerSession) Root() ([32]byte, error) { - return _MerkleTreeManager.Contract.Root(&_MerkleTreeManager.CallOpts) +// InitializableInitialized represents a Initialized event raised by the Initializable contract. +type InitializableInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function tree() view returns(uint256 count) -func (_MerkleTreeManager *MerkleTreeManagerCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _MerkleTreeManager.contract.Call(opts, &out, "tree") +// Solidity: event Initialized(uint8 version) +func (_Initializable *InitializableFilterer) FilterInitialized(opts *bind.FilterOpts) (*InitializableInitializedIterator, error) { + logs, sub, err := _Initializable.contract.FilterLogs(opts, "Initialized") if err != nil { - return *new(*big.Int), err + return nil, err } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - + return &InitializableInitializedIterator{contract: _Initializable.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function tree() view returns(uint256 count) -func (_MerkleTreeManager *MerkleTreeManagerSession) Tree() (*big.Int, error) { - return _MerkleTreeManager.Contract.Tree(&_MerkleTreeManager.CallOpts) +// Solidity: event Initialized(uint8 version) +func (_Initializable *InitializableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *InitializableInitialized) (event.Subscription, error) { + + logs, sub, err := _Initializable.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(InitializableInitialized) + if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// Tree is a free data retrieval call binding the contract method 0xfd54b228. +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. // -// Solidity: function tree() view returns(uint256 count) -func (_MerkleTreeManager *MerkleTreeManagerCallerSession) Tree() (*big.Int, error) { - return _MerkleTreeManager.Contract.Tree(&_MerkleTreeManager.CallOpts) +// Solidity: event Initialized(uint8 version) +func (_Initializable *InitializableFilterer) ParseInitialized(log types.Log) (*InitializableInitialized, error) { + event := new(InitializableInitialized) + if err := _Initializable.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// MessageMetaData contains all meta data concerning the Message contract. -var MessageMetaData = &bind.MetaData{ +// MerkleLibMetaData contains all meta data concerning the MerkleLib contract. +var MerkleLibMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205b0426a88e5a1b0384a5cea98fed44120bb489adf91d82da5fd0332744f1bb1b64736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208c9e733f9ac0589d4e1d3269ad7a58e7124ea1bb40c5ed969a517b37a1cf0d0a64736f6c634300080d0033", } -// MessageABI is the input ABI used to generate the binding from. -// Deprecated: Use MessageMetaData.ABI instead. -var MessageABI = MessageMetaData.ABI +// MerkleLibABI is the input ABI used to generate the binding from. +// Deprecated: Use MerkleLibMetaData.ABI instead. +var MerkleLibABI = MerkleLibMetaData.ABI -// MessageBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use MessageMetaData.Bin instead. -var MessageBin = MessageMetaData.Bin +// MerkleLibBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MerkleLibMetaData.Bin instead. +var MerkleLibBin = MerkleLibMetaData.Bin -// DeployMessage deploys a new Ethereum contract, binding an instance of Message to it. -func DeployMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Message, error) { - parsed, err := MessageMetaData.GetAbi() +// DeployMerkleLib deploys a new Ethereum contract, binding an instance of MerkleLib to it. +func DeployMerkleLib(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MerkleLib, error) { + parsed, err := MerkleLibMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -4820,111 +6148,111 @@ func DeployMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (commo return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MessageBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MerkleLibBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil + return address, tx, &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil } -// Message is an auto generated Go binding around an Ethereum contract. -type Message struct { - MessageCaller // Read-only binding to the contract - MessageTransactor // Write-only binding to the contract - MessageFilterer // Log filterer for contract events +// MerkleLib is an auto generated Go binding around an Ethereum contract. +type MerkleLib struct { + MerkleLibCaller // Read-only binding to the contract + MerkleLibTransactor // Write-only binding to the contract + MerkleLibFilterer // Log filterer for contract events } -// MessageCaller is an auto generated read-only Go binding around an Ethereum contract. -type MessageCaller struct { +// MerkleLibCaller is an auto generated read-only Go binding around an Ethereum contract. +type MerkleLibCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type MessageTransactor struct { +// MerkleLibTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MerkleLibTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type MessageFilterer struct { +// MerkleLibFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MerkleLibFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// MessageSession is an auto generated Go binding around an Ethereum contract, +// MerkleLibSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type MessageSession struct { - Contract *Message // Generic contract binding to set the session for +type MerkleLibSession struct { + Contract *MerkleLib // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// MerkleLibCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type MessageCallerSession struct { - Contract *MessageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type MerkleLibCallerSession struct { + Contract *MerkleLibCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// MessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// MerkleLibTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type MessageTransactorSession struct { - Contract *MessageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type MerkleLibTransactorSession struct { + Contract *MerkleLibTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// MessageRaw is an auto generated low-level Go binding around an Ethereum contract. -type MessageRaw struct { - Contract *Message // Generic contract binding to access the raw methods on +// MerkleLibRaw is an auto generated low-level Go binding around an Ethereum contract. +type MerkleLibRaw struct { + Contract *MerkleLib // Generic contract binding to access the raw methods on } -// MessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type MessageCallerRaw struct { - Contract *MessageCaller // Generic read-only contract binding to access the raw methods on +// MerkleLibCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MerkleLibCallerRaw struct { + Contract *MerkleLibCaller // Generic read-only contract binding to access the raw methods on } -// MessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type MessageTransactorRaw struct { - Contract *MessageTransactor // Generic write-only contract binding to access the raw methods on +// MerkleLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MerkleLibTransactorRaw struct { + Contract *MerkleLibTransactor // Generic write-only contract binding to access the raw methods on } -// NewMessage creates a new instance of Message, bound to a specific deployed contract. -func NewMessage(address common.Address, backend bind.ContractBackend) (*Message, error) { - contract, err := bindMessage(address, backend, backend, backend) +// NewMerkleLib creates a new instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLib(address common.Address, backend bind.ContractBackend) (*MerkleLib, error) { + contract, err := bindMerkleLib(address, backend, backend, backend) if err != nil { return nil, err } - return &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil + return &MerkleLib{MerkleLibCaller: MerkleLibCaller{contract: contract}, MerkleLibTransactor: MerkleLibTransactor{contract: contract}, MerkleLibFilterer: MerkleLibFilterer{contract: contract}}, nil } -// NewMessageCaller creates a new read-only instance of Message, bound to a specific deployed contract. -func NewMessageCaller(address common.Address, caller bind.ContractCaller) (*MessageCaller, error) { - contract, err := bindMessage(address, caller, nil, nil) +// NewMerkleLibCaller creates a new read-only instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibCaller(address common.Address, caller bind.ContractCaller) (*MerkleLibCaller, error) { + contract, err := bindMerkleLib(address, caller, nil, nil) if err != nil { return nil, err } - return &MessageCaller{contract: contract}, nil + return &MerkleLibCaller{contract: contract}, nil } -// NewMessageTransactor creates a new write-only instance of Message, bound to a specific deployed contract. -func NewMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*MessageTransactor, error) { - contract, err := bindMessage(address, nil, transactor, nil) +// NewMerkleLibTransactor creates a new write-only instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibTransactor(address common.Address, transactor bind.ContractTransactor) (*MerkleLibTransactor, error) { + contract, err := bindMerkleLib(address, nil, transactor, nil) if err != nil { return nil, err } - return &MessageTransactor{contract: contract}, nil + return &MerkleLibTransactor{contract: contract}, nil } -// NewMessageFilterer creates a new log filterer instance of Message, bound to a specific deployed contract. -func NewMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*MessageFilterer, error) { - contract, err := bindMessage(address, nil, nil, filterer) +// NewMerkleLibFilterer creates a new log filterer instance of MerkleLib, bound to a specific deployed contract. +func NewMerkleLibFilterer(address common.Address, filterer bind.ContractFilterer) (*MerkleLibFilterer, error) { + contract, err := bindMerkleLib(address, nil, nil, filterer) if err != nil { return nil, err } - return &MessageFilterer{contract: contract}, nil + return &MerkleLibFilterer{contract: contract}, nil } -// bindMessage binds a generic wrapper to an already deployed contract. -func bindMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(MessageABI)) +// bindMerkleLib binds a generic wrapper to an already deployed contract. +func bindMerkleLib(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MerkleLibABI)) if err != nil { return nil, err } @@ -4935,156 +6263,179 @@ func bindMessage(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Message *MessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Message.Contract.MessageCaller.contract.Call(opts, result, method, params...) +func (_MerkleLib *MerkleLibRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MerkleLib.Contract.MerkleLibCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Message *MessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Message.Contract.MessageTransactor.contract.Transfer(opts) +func (_MerkleLib *MerkleLibRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MerkleLib.Contract.MerkleLibTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Message *MessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Message.Contract.MessageTransactor.contract.Transact(opts, method, params...) +func (_MerkleLib *MerkleLibRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MerkleLib.Contract.MerkleLibTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Message *MessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Message.Contract.contract.Call(opts, result, method, params...) +func (_MerkleLib *MerkleLibCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MerkleLib.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Message *MessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Message.Contract.contract.Transfer(opts) +func (_MerkleLib *MerkleLibTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MerkleLib.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Message.Contract.contract.Transact(opts, method, params...) +func (_MerkleLib *MerkleLibTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MerkleLib.Contract.contract.Transact(opts, method, params...) } -// OwnableMetaData contains all meta data concerning the Ownable contract. -var OwnableMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +// MerkleTreeManagerMetaData contains all meta data concerning the MerkleTreeManager contract. +var MerkleTreeManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", Sigs: map[string]string{ - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "f2fde38b": "transferOwnership(address)", + "06661abd": "count()", + "7ea97f40": "historicalRoots(uint256)", + "ebf0c717": "root()", + "fd54b228": "tree()", }, + Bin: "0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220a5ab9978e9fd162d72901677ca68624f59d21c35b8982bd3d593e120c7e5016c64736f6c634300080d0033", } -// OwnableABI is the input ABI used to generate the binding from. -// Deprecated: Use OwnableMetaData.ABI instead. -var OwnableABI = OwnableMetaData.ABI +// MerkleTreeManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use MerkleTreeManagerMetaData.ABI instead. +var MerkleTreeManagerABI = MerkleTreeManagerMetaData.ABI -// Deprecated: Use OwnableMetaData.Sigs instead. -// OwnableFuncSigs maps the 4-byte function signature to its string representation. -var OwnableFuncSigs = OwnableMetaData.Sigs +// Deprecated: Use MerkleTreeManagerMetaData.Sigs instead. +// MerkleTreeManagerFuncSigs maps the 4-byte function signature to its string representation. +var MerkleTreeManagerFuncSigs = MerkleTreeManagerMetaData.Sigs -// Ownable is an auto generated Go binding around an Ethereum contract. -type Ownable struct { - OwnableCaller // Read-only binding to the contract - OwnableTransactor // Write-only binding to the contract - OwnableFilterer // Log filterer for contract events +// MerkleTreeManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MerkleTreeManagerMetaData.Bin instead. +var MerkleTreeManagerBin = MerkleTreeManagerMetaData.Bin + +// DeployMerkleTreeManager deploys a new Ethereum contract, binding an instance of MerkleTreeManager to it. +func DeployMerkleTreeManager(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *MerkleTreeManager, error) { + parsed, err := MerkleTreeManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MerkleTreeManagerBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MerkleTreeManager{MerkleTreeManagerCaller: MerkleTreeManagerCaller{contract: contract}, MerkleTreeManagerTransactor: MerkleTreeManagerTransactor{contract: contract}, MerkleTreeManagerFilterer: MerkleTreeManagerFilterer{contract: contract}}, nil } -// OwnableCaller is an auto generated read-only Go binding around an Ethereum contract. -type OwnableCaller struct { +// MerkleTreeManager is an auto generated Go binding around an Ethereum contract. +type MerkleTreeManager struct { + MerkleTreeManagerCaller // Read-only binding to the contract + MerkleTreeManagerTransactor // Write-only binding to the contract + MerkleTreeManagerFilterer // Log filterer for contract events +} + +// MerkleTreeManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type MerkleTreeManagerCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableTransactor is an auto generated write-only Go binding around an Ethereum contract. -type OwnableTransactor struct { +// MerkleTreeManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MerkleTreeManagerTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type OwnableFilterer struct { +// MerkleTreeManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MerkleTreeManagerFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableSession is an auto generated Go binding around an Ethereum contract, +// MerkleTreeManagerSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type OwnableSession struct { - Contract *Ownable // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type MerkleTreeManagerSession struct { + Contract *MerkleTreeManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// MerkleTreeManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type OwnableCallerSession struct { - Contract *OwnableCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type MerkleTreeManagerCallerSession struct { + Contract *MerkleTreeManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// OwnableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// MerkleTreeManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type OwnableTransactorSession struct { - Contract *OwnableTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type MerkleTreeManagerTransactorSession struct { + Contract *MerkleTreeManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableRaw is an auto generated low-level Go binding around an Ethereum contract. -type OwnableRaw struct { - Contract *Ownable // Generic contract binding to access the raw methods on +// MerkleTreeManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type MerkleTreeManagerRaw struct { + Contract *MerkleTreeManager // Generic contract binding to access the raw methods on } -// OwnableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type OwnableCallerRaw struct { - Contract *OwnableCaller // Generic read-only contract binding to access the raw methods on +// MerkleTreeManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MerkleTreeManagerCallerRaw struct { + Contract *MerkleTreeManagerCaller // Generic read-only contract binding to access the raw methods on } -// OwnableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type OwnableTransactorRaw struct { - Contract *OwnableTransactor // Generic write-only contract binding to access the raw methods on +// MerkleTreeManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MerkleTreeManagerTransactorRaw struct { + Contract *MerkleTreeManagerTransactor // Generic write-only contract binding to access the raw methods on } -// NewOwnable creates a new instance of Ownable, bound to a specific deployed contract. -func NewOwnable(address common.Address, backend bind.ContractBackend) (*Ownable, error) { - contract, err := bindOwnable(address, backend, backend, backend) +// NewMerkleTreeManager creates a new instance of MerkleTreeManager, bound to a specific deployed contract. +func NewMerkleTreeManager(address common.Address, backend bind.ContractBackend) (*MerkleTreeManager, error) { + contract, err := bindMerkleTreeManager(address, backend, backend, backend) if err != nil { return nil, err } - return &Ownable{OwnableCaller: OwnableCaller{contract: contract}, OwnableTransactor: OwnableTransactor{contract: contract}, OwnableFilterer: OwnableFilterer{contract: contract}}, nil + return &MerkleTreeManager{MerkleTreeManagerCaller: MerkleTreeManagerCaller{contract: contract}, MerkleTreeManagerTransactor: MerkleTreeManagerTransactor{contract: contract}, MerkleTreeManagerFilterer: MerkleTreeManagerFilterer{contract: contract}}, nil } -// NewOwnableCaller creates a new read-only instance of Ownable, bound to a specific deployed contract. -func NewOwnableCaller(address common.Address, caller bind.ContractCaller) (*OwnableCaller, error) { - contract, err := bindOwnable(address, caller, nil, nil) +// NewMerkleTreeManagerCaller creates a new read-only instance of MerkleTreeManager, bound to a specific deployed contract. +func NewMerkleTreeManagerCaller(address common.Address, caller bind.ContractCaller) (*MerkleTreeManagerCaller, error) { + contract, err := bindMerkleTreeManager(address, caller, nil, nil) if err != nil { return nil, err } - return &OwnableCaller{contract: contract}, nil + return &MerkleTreeManagerCaller{contract: contract}, nil } -// NewOwnableTransactor creates a new write-only instance of Ownable, bound to a specific deployed contract. -func NewOwnableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableTransactor, error) { - contract, err := bindOwnable(address, nil, transactor, nil) +// NewMerkleTreeManagerTransactor creates a new write-only instance of MerkleTreeManager, bound to a specific deployed contract. +func NewMerkleTreeManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*MerkleTreeManagerTransactor, error) { + contract, err := bindMerkleTreeManager(address, nil, transactor, nil) if err != nil { return nil, err } - return &OwnableTransactor{contract: contract}, nil + return &MerkleTreeManagerTransactor{contract: contract}, nil } -// NewOwnableFilterer creates a new log filterer instance of Ownable, bound to a specific deployed contract. -func NewOwnableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableFilterer, error) { - contract, err := bindOwnable(address, nil, nil, filterer) +// NewMerkleTreeManagerFilterer creates a new log filterer instance of MerkleTreeManager, bound to a specific deployed contract. +func NewMerkleTreeManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*MerkleTreeManagerFilterer, error) { + contract, err := bindMerkleTreeManager(address, nil, nil, filterer) if err != nil { return nil, err } - return &OwnableFilterer{contract: contract}, nil + return &MerkleTreeManagerFilterer{contract: contract}, nil } -// bindOwnable binds a generic wrapper to an already deployed contract. -func bindOwnable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(OwnableABI)) +// bindMerkleTreeManager binds a generic wrapper to an already deployed contract. +func bindMerkleTreeManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MerkleTreeManagerABI)) if err != nil { return nil, err } @@ -5095,269 +6446,340 @@ func bindOwnable(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Ownable *OwnableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Ownable.Contract.OwnableCaller.contract.Call(opts, result, method, params...) +func (_MerkleTreeManager *MerkleTreeManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MerkleTreeManager.Contract.MerkleTreeManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MerkleTreeManager *MerkleTreeManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MerkleTreeManager.Contract.MerkleTreeManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MerkleTreeManager *MerkleTreeManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MerkleTreeManager.Contract.MerkleTreeManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_MerkleTreeManager *MerkleTreeManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MerkleTreeManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_MerkleTreeManager *MerkleTreeManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MerkleTreeManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MerkleTreeManager *MerkleTreeManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MerkleTreeManager.Contract.contract.Transact(opts, method, params...) } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Ownable *OwnableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Ownable.Contract.OwnableTransactor.contract.Transfer(opts) -} +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_MerkleTreeManager *MerkleTreeManagerCaller) Count(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MerkleTreeManager.contract.Call(opts, &out, "count") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) -// Transact invokes the (paid) contract method with params as input values. -func (_Ownable *OwnableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Ownable.Contract.OwnableTransactor.contract.Transact(opts, method, params...) -} + return out0, err -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_Ownable *OwnableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Ownable.Contract.contract.Call(opts, result, method, params...) } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_Ownable *OwnableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Ownable.Contract.contract.Transfer(opts) +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_MerkleTreeManager *MerkleTreeManagerSession) Count() (*big.Int, error) { + return _MerkleTreeManager.Contract.Count(&_MerkleTreeManager.CallOpts) } -// Transact invokes the (paid) contract method with params as input values. -func (_Ownable *OwnableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Ownable.Contract.contract.Transact(opts, method, params...) +// Count is a free data retrieval call binding the contract method 0x06661abd. +// +// Solidity: function count() view returns(uint256) +func (_MerkleTreeManager *MerkleTreeManagerCallerSession) Count() (*big.Int, error) { + return _MerkleTreeManager.Contract.Count(&_MerkleTreeManager.CallOpts) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. // -// Solidity: function owner() view returns(address) -func (_Ownable *OwnableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_MerkleTreeManager *MerkleTreeManagerCaller) HistoricalRoots(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { var out []interface{} - err := _Ownable.contract.Call(opts, &out, "owner") + err := _MerkleTreeManager.contract.Call(opts, &out, "historicalRoots", arg0) if err != nil { - return *new(common.Address), err + return *new([32]byte), err } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) return out0, err } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. // -// Solidity: function owner() view returns(address) -func (_Ownable *OwnableSession) Owner() (common.Address, error) { - return _Ownable.Contract.Owner(&_Ownable.CallOpts) +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_MerkleTreeManager *MerkleTreeManagerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _MerkleTreeManager.Contract.HistoricalRoots(&_MerkleTreeManager.CallOpts, arg0) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// HistoricalRoots is a free data retrieval call binding the contract method 0x7ea97f40. // -// Solidity: function owner() view returns(address) -func (_Ownable *OwnableCallerSession) Owner() (common.Address, error) { - return _Ownable.Contract.Owner(&_Ownable.CallOpts) +// Solidity: function historicalRoots(uint256 ) view returns(bytes32) +func (_MerkleTreeManager *MerkleTreeManagerCallerSession) HistoricalRoots(arg0 *big.Int) ([32]byte, error) { + return _MerkleTreeManager.Contract.HistoricalRoots(&_MerkleTreeManager.CallOpts, arg0) } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// Root is a free data retrieval call binding the contract method 0xebf0c717. // -// Solidity: function renounceOwnership() returns() -func (_Ownable *OwnableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Ownable.contract.Transact(opts, "renounceOwnership") +// Solidity: function root() view returns(bytes32) +func (_MerkleTreeManager *MerkleTreeManagerCaller) Root(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _MerkleTreeManager.contract.Call(opts, &out, "root") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// Root is a free data retrieval call binding the contract method 0xebf0c717. // -// Solidity: function renounceOwnership() returns() -func (_Ownable *OwnableSession) RenounceOwnership() (*types.Transaction, error) { - return _Ownable.Contract.RenounceOwnership(&_Ownable.TransactOpts) +// Solidity: function root() view returns(bytes32) +func (_MerkleTreeManager *MerkleTreeManagerSession) Root() ([32]byte, error) { + return _MerkleTreeManager.Contract.Root(&_MerkleTreeManager.CallOpts) } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// Root is a free data retrieval call binding the contract method 0xebf0c717. // -// Solidity: function renounceOwnership() returns() -func (_Ownable *OwnableTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _Ownable.Contract.RenounceOwnership(&_Ownable.TransactOpts) +// Solidity: function root() view returns(bytes32) +func (_MerkleTreeManager *MerkleTreeManagerCallerSession) Root() ([32]byte, error) { + return _MerkleTreeManager.Contract.Root(&_MerkleTreeManager.CallOpts) } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// Tree is a free data retrieval call binding the contract method 0xfd54b228. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_Ownable *OwnableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _Ownable.contract.Transact(opts, "transferOwnership", newOwner) +// Solidity: function tree() view returns(uint256 count) +func (_MerkleTreeManager *MerkleTreeManagerCaller) Tree(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MerkleTreeManager.contract.Call(opts, &out, "tree") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// Tree is a free data retrieval call binding the contract method 0xfd54b228. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_Ownable *OwnableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Ownable.Contract.TransferOwnership(&_Ownable.TransactOpts, newOwner) +// Solidity: function tree() view returns(uint256 count) +func (_MerkleTreeManager *MerkleTreeManagerSession) Tree() (*big.Int, error) { + return _MerkleTreeManager.Contract.Tree(&_MerkleTreeManager.CallOpts) } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// Tree is a free data retrieval call binding the contract method 0xfd54b228. // -// Solidity: function transferOwnership(address newOwner) returns() -func (_Ownable *OwnableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _Ownable.Contract.TransferOwnership(&_Ownable.TransactOpts, newOwner) +// Solidity: function tree() view returns(uint256 count) +func (_MerkleTreeManager *MerkleTreeManagerCallerSession) Tree() (*big.Int, error) { + return _MerkleTreeManager.Contract.Tree(&_MerkleTreeManager.CallOpts) } -// OwnableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Ownable contract. -type OwnableOwnershipTransferredIterator struct { - Event *OwnableOwnershipTransferred // Event containing the contract specifics and raw log +// MessageMetaData contains all meta data concerning the Message contract. +var MessageMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205ae5747286052a50a840c40a36debae4290685b79799018ad5492a14cd0d700164736f6c634300080d0033", +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// MessageABI is the input ABI used to generate the binding from. +// Deprecated: Use MessageMetaData.ABI instead. +var MessageABI = MessageMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// MessageBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MessageMetaData.Bin instead. +var MessageBin = MessageMetaData.Bin -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *OwnableOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// DeployMessage deploys a new Ethereum contract, binding an instance of Message to it. +func DeployMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Message, error) { + parsed, err := MessageMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(OwnableOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(OwnableOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MessageBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } + return address, tx, &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *OwnableOwnershipTransferredIterator) Error() error { - return it.fail +// Message is an auto generated Go binding around an Ethereum contract. +type Message struct { + MessageCaller // Read-only binding to the contract + MessageTransactor // Write-only binding to the contract + MessageFilterer // Log filterer for contract events } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *OwnableOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil +// MessageCaller is an auto generated read-only Go binding around an Ethereum contract. +type MessageCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableOwnershipTransferred represents a OwnershipTransferred event raised by the Ownable contract. -type OwnableOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// MessageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MessageTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MessageFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MessageSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MessageSession struct { + Contract *Message // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MessageCallerSession struct { + Contract *MessageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MessageTransactorSession struct { + Contract *MessageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MessageRaw is an auto generated low-level Go binding around an Ethereum contract. +type MessageRaw struct { + Contract *Message // Generic contract binding to access the raw methods on +} + +// MessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MessageCallerRaw struct { + Contract *MessageCaller // Generic read-only contract binding to access the raw methods on } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Ownable *OwnableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableOwnershipTransferredIterator, error) { +// MessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MessageTransactorRaw struct { + Contract *MessageTransactor // Generic write-only contract binding to access the raw methods on +} - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) +// NewMessage creates a new instance of Message, bound to a specific deployed contract. +func NewMessage(address common.Address, backend bind.ContractBackend) (*Message, error) { + contract, err := bindMessage(address, backend, backend, backend) + if err != nil { + return nil, err } + return &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil +} - logs, sub, err := _Ownable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewMessageCaller creates a new read-only instance of Message, bound to a specific deployed contract. +func NewMessageCaller(address common.Address, caller bind.ContractCaller) (*MessageCaller, error) { + contract, err := bindMessage(address, caller, nil, nil) if err != nil { return nil, err } - return &OwnableOwnershipTransferredIterator{contract: _Ownable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &MessageCaller{contract: contract}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Ownable *OwnableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) +// NewMessageTransactor creates a new write-only instance of Message, bound to a specific deployed contract. +func NewMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*MessageTransactor, error) { + contract, err := bindMessage(address, nil, transactor, nil) + if err != nil { + return nil, err } + return &MessageTransactor{contract: contract}, nil +} - logs, sub, err := _Ownable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) +// NewMessageFilterer creates a new log filterer instance of Message, bound to a specific deployed contract. +func NewMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*MessageFilterer, error) { + contract, err := bindMessage(address, nil, nil, filterer) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(OwnableOwnershipTransferred) - if err := _Ownable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &MessageFilterer{contract: contract}, nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_Ownable *OwnableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableOwnershipTransferred, error) { - event := new(OwnableOwnershipTransferred) - if err := _Ownable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// bindMessage binds a generic wrapper to an already deployed contract. +func bindMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(MessageABI)) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// OwnableUpgradeableMetaData contains all meta data concerning the OwnableUpgradeable contract. -var OwnableUpgradeableMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Message *MessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Message.Contract.MessageCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Message *MessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Message.Contract.MessageTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Message *MessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Message.Contract.MessageTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Message *MessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Message.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Message *MessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Message.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Message.Contract.contract.Transact(opts, method, params...) +} + +// OwnableMetaData contains all meta data concerning the Ownable contract. +var OwnableMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Sigs: map[string]string{ "8da5cb5b": "owner()", "715018a6": "renounceOwnership()", @@ -5365,112 +6787,112 @@ var OwnableUpgradeableMetaData = &bind.MetaData{ }, } -// OwnableUpgradeableABI is the input ABI used to generate the binding from. -// Deprecated: Use OwnableUpgradeableMetaData.ABI instead. -var OwnableUpgradeableABI = OwnableUpgradeableMetaData.ABI +// OwnableABI is the input ABI used to generate the binding from. +// Deprecated: Use OwnableMetaData.ABI instead. +var OwnableABI = OwnableMetaData.ABI -// Deprecated: Use OwnableUpgradeableMetaData.Sigs instead. -// OwnableUpgradeableFuncSigs maps the 4-byte function signature to its string representation. -var OwnableUpgradeableFuncSigs = OwnableUpgradeableMetaData.Sigs +// Deprecated: Use OwnableMetaData.Sigs instead. +// OwnableFuncSigs maps the 4-byte function signature to its string representation. +var OwnableFuncSigs = OwnableMetaData.Sigs -// OwnableUpgradeable is an auto generated Go binding around an Ethereum contract. -type OwnableUpgradeable struct { - OwnableUpgradeableCaller // Read-only binding to the contract - OwnableUpgradeableTransactor // Write-only binding to the contract - OwnableUpgradeableFilterer // Log filterer for contract events +// Ownable is an auto generated Go binding around an Ethereum contract. +type Ownable struct { + OwnableCaller // Read-only binding to the contract + OwnableTransactor // Write-only binding to the contract + OwnableFilterer // Log filterer for contract events } -// OwnableUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. -type OwnableUpgradeableCaller struct { +// OwnableCaller is an auto generated read-only Go binding around an Ethereum contract. +type OwnableCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. -type OwnableUpgradeableTransactor struct { +// OwnableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type OwnableTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type OwnableUpgradeableFilterer struct { +// OwnableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OwnableFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// OwnableUpgradeableSession is an auto generated Go binding around an Ethereum contract, +// OwnableSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type OwnableUpgradeableSession struct { - Contract *OwnableUpgradeable // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type OwnableSession struct { + Contract *Ownable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// OwnableCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type OwnableUpgradeableCallerSession struct { - Contract *OwnableUpgradeableCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type OwnableCallerSession struct { + Contract *OwnableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// OwnableUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// OwnableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type OwnableUpgradeableTransactorSession struct { - Contract *OwnableUpgradeableTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type OwnableTransactorSession struct { + Contract *OwnableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// OwnableUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. -type OwnableUpgradeableRaw struct { - Contract *OwnableUpgradeable // Generic contract binding to access the raw methods on +// OwnableRaw is an auto generated low-level Go binding around an Ethereum contract. +type OwnableRaw struct { + Contract *Ownable // Generic contract binding to access the raw methods on } -// OwnableUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type OwnableUpgradeableCallerRaw struct { - Contract *OwnableUpgradeableCaller // Generic read-only contract binding to access the raw methods on +// OwnableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OwnableCallerRaw struct { + Contract *OwnableCaller // Generic read-only contract binding to access the raw methods on } -// OwnableUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type OwnableUpgradeableTransactorRaw struct { - Contract *OwnableUpgradeableTransactor // Generic write-only contract binding to access the raw methods on +// OwnableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OwnableTransactorRaw struct { + Contract *OwnableTransactor // Generic write-only contract binding to access the raw methods on } -// NewOwnableUpgradeable creates a new instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeable(address common.Address, backend bind.ContractBackend) (*OwnableUpgradeable, error) { - contract, err := bindOwnableUpgradeable(address, backend, backend, backend) +// NewOwnable creates a new instance of Ownable, bound to a specific deployed contract. +func NewOwnable(address common.Address, backend bind.ContractBackend) (*Ownable, error) { + contract, err := bindOwnable(address, backend, backend, backend) if err != nil { return nil, err } - return &OwnableUpgradeable{OwnableUpgradeableCaller: OwnableUpgradeableCaller{contract: contract}, OwnableUpgradeableTransactor: OwnableUpgradeableTransactor{contract: contract}, OwnableUpgradeableFilterer: OwnableUpgradeableFilterer{contract: contract}}, nil + return &Ownable{OwnableCaller: OwnableCaller{contract: contract}, OwnableTransactor: OwnableTransactor{contract: contract}, OwnableFilterer: OwnableFilterer{contract: contract}}, nil } -// NewOwnableUpgradeableCaller creates a new read-only instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*OwnableUpgradeableCaller, error) { - contract, err := bindOwnableUpgradeable(address, caller, nil, nil) +// NewOwnableCaller creates a new read-only instance of Ownable, bound to a specific deployed contract. +func NewOwnableCaller(address common.Address, caller bind.ContractCaller) (*OwnableCaller, error) { + contract, err := bindOwnable(address, caller, nil, nil) if err != nil { return nil, err } - return &OwnableUpgradeableCaller{contract: contract}, nil + return &OwnableCaller{contract: contract}, nil } -// NewOwnableUpgradeableTransactor creates a new write-only instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableUpgradeableTransactor, error) { - contract, err := bindOwnableUpgradeable(address, nil, transactor, nil) +// NewOwnableTransactor creates a new write-only instance of Ownable, bound to a specific deployed contract. +func NewOwnableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableTransactor, error) { + contract, err := bindOwnable(address, nil, transactor, nil) if err != nil { return nil, err } - return &OwnableUpgradeableTransactor{contract: contract}, nil + return &OwnableTransactor{contract: contract}, nil } -// NewOwnableUpgradeableFilterer creates a new log filterer instance of OwnableUpgradeable, bound to a specific deployed contract. -func NewOwnableUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableUpgradeableFilterer, error) { - contract, err := bindOwnableUpgradeable(address, nil, nil, filterer) +// NewOwnableFilterer creates a new log filterer instance of Ownable, bound to a specific deployed contract. +func NewOwnableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableFilterer, error) { + contract, err := bindOwnable(address, nil, nil, filterer) if err != nil { return nil, err } - return &OwnableUpgradeableFilterer{contract: contract}, nil + return &OwnableFilterer{contract: contract}, nil } -// bindOwnableUpgradeable binds a generic wrapper to an already deployed contract. -func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(OwnableUpgradeableABI)) +// bindOwnable binds a generic wrapper to an already deployed contract. +func bindOwnable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(OwnableABI)) if err != nil { return nil, err } @@ -5481,46 +6903,46 @@ func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _OwnableUpgradeable.Contract.OwnableUpgradeableCaller.contract.Call(opts, result, method, params...) +func (_Ownable *OwnableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Ownable.Contract.OwnableCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transfer(opts) +func (_Ownable *OwnableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ownable.Contract.OwnableTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transact(opts, method, params...) +func (_Ownable *OwnableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Ownable.Contract.OwnableTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_OwnableUpgradeable *OwnableUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _OwnableUpgradeable.Contract.contract.Call(opts, result, method, params...) +func (_Ownable *OwnableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Ownable.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.contract.Transfer(opts) +func (_Ownable *OwnableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ownable.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.contract.Transact(opts, method, params...) +func (_Ownable *OwnableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Ownable.Contract.contract.Transact(opts, method, params...) } // Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // // Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +func (_Ownable *OwnableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _OwnableUpgradeable.contract.Call(opts, &out, "owner") + err := _Ownable.contract.Call(opts, &out, "owner") if err != nil { return *new(common.Address), err @@ -5535,196 +6957,62 @@ func (_OwnableUpgradeable *OwnableUpgradeableCaller) Owner(opts *bind.CallOpts) // Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // // Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableSession) Owner() (common.Address, error) { - return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) +func (_Ownable *OwnableSession) Owner() (common.Address, error) { + return _Ownable.Contract.Owner(&_Ownable.CallOpts) } // Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // // Solidity: function owner() view returns(address) -func (_OwnableUpgradeable *OwnableUpgradeableCallerSession) Owner() (common.Address, error) { - return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) +func (_Ownable *OwnableCallerSession) Owner() (common.Address, error) { + return _Ownable.Contract.Owner(&_Ownable.CallOpts) } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // // Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _OwnableUpgradeable.contract.Transact(opts, "renounceOwnership") +func (_Ownable *OwnableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Ownable.contract.Transact(opts, "renounceOwnership") } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // // Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) +func (_Ownable *OwnableSession) RenounceOwnership() (*types.Transaction, error) { + return _Ownable.Contract.RenounceOwnership(&_Ownable.TransactOpts) } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // // Solidity: function renounceOwnership() returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) +func (_Ownable *OwnableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _Ownable.Contract.RenounceOwnership(&_Ownable.TransactOpts) } // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) +func (_Ownable *OwnableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Ownable.contract.Transact(opts, "transferOwnership", newOwner) } // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +func (_Ownable *OwnableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Ownable.Contract.TransferOwnership(&_Ownable.TransactOpts, newOwner) } // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() -func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) -} - -// OwnableUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the OwnableUpgradeable contract. -type OwnableUpgradeableInitializedIterator struct { - Event *OwnableUpgradeableInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *OwnableUpgradeableInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(OwnableUpgradeableInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(OwnableUpgradeableInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *OwnableUpgradeableInitializedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *OwnableUpgradeableInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// OwnableUpgradeableInitialized represents a Initialized event raised by the OwnableUpgradeable contract. -type OwnableUpgradeableInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*OwnableUpgradeableInitializedIterator, error) { - - logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return &OwnableUpgradeableInitializedIterator{contract: _OwnableUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil -} - -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableInitialized) (event.Subscription, error) { - - logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(OwnableUpgradeableInitialized) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseInitialized(log types.Log) (*OwnableUpgradeableInitialized, error) { - event := new(OwnableUpgradeableInitialized) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +func (_Ownable *OwnableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Ownable.Contract.TransferOwnership(&_Ownable.TransactOpts, newOwner) } -// OwnableUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the OwnableUpgradeable contract. -type OwnableUpgradeableOwnershipTransferredIterator struct { - Event *OwnableUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log +// OwnableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Ownable contract. +type OwnableOwnershipTransferredIterator struct { + Event *OwnableOwnershipTransferred // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -5738,7 +7026,7 @@ type OwnableUpgradeableOwnershipTransferredIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { +func (it *OwnableOwnershipTransferredIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -5747,7 +7035,7 @@ func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(OwnableUpgradeableOwnershipTransferred) + it.Event = new(OwnableOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5762,7 +7050,7 @@ func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(OwnableUpgradeableOwnershipTransferred) + it.Event = new(OwnableOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -5778,19 +7066,19 @@ func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Error() error { +func (it *OwnableOwnershipTransferredIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *OwnableUpgradeableOwnershipTransferredIterator) Close() error { +func (it *OwnableOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -// OwnableUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the OwnableUpgradeable contract. -type OwnableUpgradeableOwnershipTransferred struct { +// OwnableOwnershipTransferred represents a OwnershipTransferred event raised by the Ownable contract. +type OwnableOwnershipTransferred struct { PreviousOwner common.Address NewOwner common.Address Raw types.Log // Blockchain specific contextual infos @@ -5799,7 +7087,7 @@ type OwnableUpgradeableOwnershipTransferred struct { // FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // // Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableUpgradeableOwnershipTransferredIterator, error) { +func (_Ownable *OwnableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableOwnershipTransferredIterator, error) { var previousOwnerRule []interface{} for _, previousOwnerItem := range previousOwner { @@ -5810,17 +7098,17 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterOwnershipTransferre newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _Ownable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } - return &OwnableUpgradeableOwnershipTransferredIterator{contract: _OwnableUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &OwnableOwnershipTransferredIterator{contract: _Ownable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } // WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // // Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { +func (_Ownable *OwnableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { var previousOwnerRule []interface{} for _, previousOwnerItem := range previousOwner { @@ -5831,7 +7119,7 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _Ownable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } @@ -5841,8 +7129,8 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(OwnableUpgradeableOwnershipTransferred) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(OwnableOwnershipTransferred) + if err := _Ownable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -5866,144 +7154,131 @@ func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred // ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // // Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableUpgradeableOwnershipTransferred, error) { - event := new(OwnableUpgradeableOwnershipTransferred) - if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -// StringsMetaData contains all meta data concerning the Strings contract. -var StringsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220840fba12deb870891a7dbc39187831add8b9804cf51a0dc6ac467b0de430082764736f6c634300080d0033", -} - -// StringsABI is the input ABI used to generate the binding from. -// Deprecated: Use StringsMetaData.ABI instead. -var StringsABI = StringsMetaData.ABI - -// StringsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use StringsMetaData.Bin instead. -var StringsBin = StringsMetaData.Bin - -// DeployStrings deploys a new Ethereum contract, binding an instance of Strings to it. -func DeployStrings(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Strings, error) { - parsed, err := StringsMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") +func (_Ownable *OwnableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableOwnershipTransferred, error) { + event := new(OwnableOwnershipTransferred) + if err := _Ownable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err } + event.Raw = log + return event, nil +} - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(StringsBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &Strings{StringsCaller: StringsCaller{contract: contract}, StringsTransactor: StringsTransactor{contract: contract}, StringsFilterer: StringsFilterer{contract: contract}}, nil +// OwnableUpgradeableMetaData contains all meta data concerning the OwnableUpgradeable contract. +var OwnableUpgradeableMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "f2fde38b": "transferOwnership(address)", + }, } -// Strings is an auto generated Go binding around an Ethereum contract. -type Strings struct { - StringsCaller // Read-only binding to the contract - StringsTransactor // Write-only binding to the contract - StringsFilterer // Log filterer for contract events +// OwnableUpgradeableABI is the input ABI used to generate the binding from. +// Deprecated: Use OwnableUpgradeableMetaData.ABI instead. +var OwnableUpgradeableABI = OwnableUpgradeableMetaData.ABI + +// Deprecated: Use OwnableUpgradeableMetaData.Sigs instead. +// OwnableUpgradeableFuncSigs maps the 4-byte function signature to its string representation. +var OwnableUpgradeableFuncSigs = OwnableUpgradeableMetaData.Sigs + +// OwnableUpgradeable is an auto generated Go binding around an Ethereum contract. +type OwnableUpgradeable struct { + OwnableUpgradeableCaller // Read-only binding to the contract + OwnableUpgradeableTransactor // Write-only binding to the contract + OwnableUpgradeableFilterer // Log filterer for contract events } -// StringsCaller is an auto generated read-only Go binding around an Ethereum contract. -type StringsCaller struct { +// OwnableUpgradeableCaller is an auto generated read-only Go binding around an Ethereum contract. +type OwnableUpgradeableCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// StringsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type StringsTransactor struct { +// OwnableUpgradeableTransactor is an auto generated write-only Go binding around an Ethereum contract. +type OwnableUpgradeableTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// StringsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type StringsFilterer struct { +// OwnableUpgradeableFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OwnableUpgradeableFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// StringsSession is an auto generated Go binding around an Ethereum contract, +// OwnableUpgradeableSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type StringsSession struct { - Contract *Strings // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type OwnableUpgradeableSession struct { + Contract *OwnableUpgradeable // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// StringsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// OwnableUpgradeableCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type StringsCallerSession struct { - Contract *StringsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type OwnableUpgradeableCallerSession struct { + Contract *OwnableUpgradeableCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// StringsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// OwnableUpgradeableTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type StringsTransactorSession struct { - Contract *StringsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type OwnableUpgradeableTransactorSession struct { + Contract *OwnableUpgradeableTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// StringsRaw is an auto generated low-level Go binding around an Ethereum contract. -type StringsRaw struct { - Contract *Strings // Generic contract binding to access the raw methods on +// OwnableUpgradeableRaw is an auto generated low-level Go binding around an Ethereum contract. +type OwnableUpgradeableRaw struct { + Contract *OwnableUpgradeable // Generic contract binding to access the raw methods on } -// StringsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type StringsCallerRaw struct { - Contract *StringsCaller // Generic read-only contract binding to access the raw methods on +// OwnableUpgradeableCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OwnableUpgradeableCallerRaw struct { + Contract *OwnableUpgradeableCaller // Generic read-only contract binding to access the raw methods on } -// StringsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type StringsTransactorRaw struct { - Contract *StringsTransactor // Generic write-only contract binding to access the raw methods on +// OwnableUpgradeableTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OwnableUpgradeableTransactorRaw struct { + Contract *OwnableUpgradeableTransactor // Generic write-only contract binding to access the raw methods on } -// NewStrings creates a new instance of Strings, bound to a specific deployed contract. -func NewStrings(address common.Address, backend bind.ContractBackend) (*Strings, error) { - contract, err := bindStrings(address, backend, backend, backend) +// NewOwnableUpgradeable creates a new instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeable(address common.Address, backend bind.ContractBackend) (*OwnableUpgradeable, error) { + contract, err := bindOwnableUpgradeable(address, backend, backend, backend) if err != nil { return nil, err } - return &Strings{StringsCaller: StringsCaller{contract: contract}, StringsTransactor: StringsTransactor{contract: contract}, StringsFilterer: StringsFilterer{contract: contract}}, nil + return &OwnableUpgradeable{OwnableUpgradeableCaller: OwnableUpgradeableCaller{contract: contract}, OwnableUpgradeableTransactor: OwnableUpgradeableTransactor{contract: contract}, OwnableUpgradeableFilterer: OwnableUpgradeableFilterer{contract: contract}}, nil } -// NewStringsCaller creates a new read-only instance of Strings, bound to a specific deployed contract. -func NewStringsCaller(address common.Address, caller bind.ContractCaller) (*StringsCaller, error) { - contract, err := bindStrings(address, caller, nil, nil) +// NewOwnableUpgradeableCaller creates a new read-only instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableCaller(address common.Address, caller bind.ContractCaller) (*OwnableUpgradeableCaller, error) { + contract, err := bindOwnableUpgradeable(address, caller, nil, nil) if err != nil { return nil, err } - return &StringsCaller{contract: contract}, nil + return &OwnableUpgradeableCaller{contract: contract}, nil } -// NewStringsTransactor creates a new write-only instance of Strings, bound to a specific deployed contract. -func NewStringsTransactor(address common.Address, transactor bind.ContractTransactor) (*StringsTransactor, error) { - contract, err := bindStrings(address, nil, transactor, nil) +// NewOwnableUpgradeableTransactor creates a new write-only instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableTransactor(address common.Address, transactor bind.ContractTransactor) (*OwnableUpgradeableTransactor, error) { + contract, err := bindOwnableUpgradeable(address, nil, transactor, nil) if err != nil { return nil, err } - return &StringsTransactor{contract: contract}, nil + return &OwnableUpgradeableTransactor{contract: contract}, nil } -// NewStringsFilterer creates a new log filterer instance of Strings, bound to a specific deployed contract. -func NewStringsFilterer(address common.Address, filterer bind.ContractFilterer) (*StringsFilterer, error) { - contract, err := bindStrings(address, nil, nil, filterer) +// NewOwnableUpgradeableFilterer creates a new log filterer instance of OwnableUpgradeable, bound to a specific deployed contract. +func NewOwnableUpgradeableFilterer(address common.Address, filterer bind.ContractFilterer) (*OwnableUpgradeableFilterer, error) { + contract, err := bindOwnableUpgradeable(address, nil, nil, filterer) if err != nil { return nil, err } - return &StringsFilterer{contract: contract}, nil + return &OwnableUpgradeableFilterer{contract: contract}, nil } -// bindStrings binds a generic wrapper to an already deployed contract. -func bindStrings(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(StringsABI)) +// bindOwnableUpgradeable binds a generic wrapper to an already deployed contract. +func bindOwnableUpgradeable(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(OwnableUpgradeableABI)) if err != nil { return nil, err } @@ -6014,230 +7289,417 @@ func bindStrings(address common.Address, caller bind.ContractCaller, transactor // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Strings *StringsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Strings.Contract.StringsCaller.contract.Call(opts, result, method, params...) +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OwnableUpgradeable.Contract.OwnableUpgradeableCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Strings *StringsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Strings.Contract.StringsTransactor.contract.Transfer(opts) +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Strings *StringsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Strings.Contract.StringsTransactor.contract.Transact(opts, method, params...) +func (_OwnableUpgradeable *OwnableUpgradeableRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.OwnableUpgradeableTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Strings *StringsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Strings.Contract.contract.Call(opts, result, method, params...) +func (_OwnableUpgradeable *OwnableUpgradeableCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OwnableUpgradeable.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Strings *StringsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Strings.Contract.contract.Transfer(opts) +func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Strings *StringsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Strings.Contract.contract.Transact(opts, method, params...) +func (_OwnableUpgradeable *OwnableUpgradeableTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.contract.Transact(opts, method, params...) } -// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. -var SystemMessageMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209c5fc3e05f7a2411166d6f55c87041b3eb88f0998e4837a2f524f3835902bfdd64736f6c634300080d0033", +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OwnableUpgradeable.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// SystemMessageABI is the input ABI used to generate the binding from. -// Deprecated: Use SystemMessageMetaData.ABI instead. -var SystemMessageABI = SystemMessageMetaData.ABI +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableSession) Owner() (common.Address, error) { + return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) +} -// SystemMessageBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use SystemMessageMetaData.Bin instead. -var SystemMessageBin = SystemMessageMetaData.Bin +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_OwnableUpgradeable *OwnableUpgradeableCallerSession) Owner() (common.Address, error) { + return _OwnableUpgradeable.Contract.Owner(&_OwnableUpgradeable.CallOpts) +} -// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. -func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { - parsed, err := SystemMessageMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OwnableUpgradeable.contract.Transact(opts, "renounceOwnership") +} - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableSession) RenounceOwnership() (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) } -// SystemMessage is an auto generated Go binding around an Ethereum contract. -type SystemMessage struct { - SystemMessageCaller // Read-only binding to the contract - SystemMessageTransactor // Write-only binding to the contract - SystemMessageFilterer // Log filterer for contract events +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.RenounceOwnership(&_OwnableUpgradeable.TransactOpts) } -// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. -type SystemMessageCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.contract.Transact(opts, "transferOwnership", newOwner) } -// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type SystemMessageTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_OwnableUpgradeable *OwnableUpgradeableTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _OwnableUpgradeable.Contract.TransferOwnership(&_OwnableUpgradeable.TransactOpts, newOwner) } -// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type SystemMessageFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// OwnableUpgradeableInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the OwnableUpgradeable contract. +type OwnableUpgradeableInitializedIterator struct { + Event *OwnableUpgradeableInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// SystemMessageSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type SystemMessageSession struct { - Contract *SystemMessage // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session -} +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OwnableUpgradeableInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type SystemMessageCallerSession struct { - Contract *SystemMessageCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session -} + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true -// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type SystemMessageTransactorSession struct { - Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. -type SystemMessageRaw struct { - Contract *SystemMessage // Generic contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OwnableUpgradeableInitializedIterator) Error() error { + return it.fail } -// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type SystemMessageCallerRaw struct { - Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OwnableUpgradeableInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type SystemMessageTransactorRaw struct { - Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on +// OwnableUpgradeableInitialized represents a Initialized event raised by the OwnableUpgradeable contract. +type OwnableUpgradeableInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { - contract, err := bindSystemMessage(address, backend, backend, backend) +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterInitialized(opts *bind.FilterOpts) (*OwnableUpgradeableInitializedIterator, error) { + + logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil + return &OwnableUpgradeableInitializedIterator{contract: _OwnableUpgradeable.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { - contract, err := bindSystemMessage(address, caller, nil, nil) +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableInitialized) (event.Subscription, error) { + + logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } - return &SystemMessageCaller{contract: contract}, nil + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OwnableUpgradeableInitialized) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { - contract, err := bindSystemMessage(address, nil, transactor, nil) - if err != nil { +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseInitialized(log types.Log) (*OwnableUpgradeableInitialized, error) { + event := new(OwnableUpgradeableInitialized) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } - return &SystemMessageTransactor{contract: contract}, nil + event.Raw = log + return event, nil } -// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. -func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { - contract, err := bindSystemMessage(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &SystemMessageFilterer{contract: contract}, nil +// OwnableUpgradeableOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the OwnableUpgradeable contract. +type OwnableUpgradeableOwnershipTransferredIterator struct { + Event *OwnableUpgradeableOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// bindSystemMessage binds a generic wrapper to an already deployed contract. -func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) - if err != nil { - return nil, err +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *OwnableUpgradeableOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(OwnableUpgradeableOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *OwnableUpgradeableOwnershipTransferredIterator) Error() error { + return it.fail } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *OwnableUpgradeableOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) +// OwnableUpgradeableOwnershipTransferred represents a OwnershipTransferred event raised by the OwnableUpgradeable contract. +type OwnableUpgradeableOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _SystemMessage.Contract.contract.Call(opts, result, method, params...) +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*OwnableUpgradeableOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _OwnableUpgradeable.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &OwnableUpgradeableOwnershipTransferredIterator{contract: _OwnableUpgradeable.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transfer(opts) +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *OwnableUpgradeableOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _OwnableUpgradeable.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(OwnableUpgradeableOwnershipTransferred) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// Transact invokes the (paid) contract method with params as input values. -func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _SystemMessage.Contract.contract.Transact(opts, method, params...) +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_OwnableUpgradeable *OwnableUpgradeableFilterer) ParseOwnershipTransferred(log types.Log) (*OwnableUpgradeableOwnershipTransferred, error) { + event := new(OwnableUpgradeableOwnershipTransferred) + if err := _OwnableUpgradeable.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// TipsMetaData contains all meta data concerning the Tips contract. -var TipsMetaData = &bind.MetaData{ +// StringsMetaData contains all meta data concerning the Strings contract. +var StringsMetaData = &bind.MetaData{ ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ebad72f7fd3317d85bf44c4b7a1658c6190a1b86b3e21188aaa637c95d1113b564736f6c634300080d0033", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e8344ff379070d013a936b22519238d053b96dac95b78d47146409ed6d790b4a64736f6c634300080d0033", } -// TipsABI is the input ABI used to generate the binding from. -// Deprecated: Use TipsMetaData.ABI instead. -var TipsABI = TipsMetaData.ABI +// StringsABI is the input ABI used to generate the binding from. +// Deprecated: Use StringsMetaData.ABI instead. +var StringsABI = StringsMetaData.ABI -// TipsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TipsMetaData.Bin instead. -var TipsBin = TipsMetaData.Bin +// StringsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use StringsMetaData.Bin instead. +var StringsBin = StringsMetaData.Bin -// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. -func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { - parsed, err := TipsMetaData.GetAbi() +// DeployStrings deploys a new Ethereum contract, binding an instance of Strings to it. +func DeployStrings(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Strings, error) { + parsed, err := StringsMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -6245,111 +7707,111 @@ func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.A return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(StringsBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil + return address, tx, &Strings{StringsCaller: StringsCaller{contract: contract}, StringsTransactor: StringsTransactor{contract: contract}, StringsFilterer: StringsFilterer{contract: contract}}, nil } -// Tips is an auto generated Go binding around an Ethereum contract. -type Tips struct { - TipsCaller // Read-only binding to the contract - TipsTransactor // Write-only binding to the contract - TipsFilterer // Log filterer for contract events +// Strings is an auto generated Go binding around an Ethereum contract. +type Strings struct { + StringsCaller // Read-only binding to the contract + StringsTransactor // Write-only binding to the contract + StringsFilterer // Log filterer for contract events } -// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TipsCaller struct { +// StringsCaller is an auto generated read-only Go binding around an Ethereum contract. +type StringsCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TipsTransactor struct { +// StringsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type StringsTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TipsFilterer struct { +// StringsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type StringsFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TipsSession is an auto generated Go binding around an Ethereum contract, +// StringsSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TipsSession struct { - Contract *Tips // Generic contract binding to set the session for +type StringsSession struct { + Contract *Strings // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// StringsCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TipsCallerSession struct { - Contract *TipsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type StringsCallerSession struct { + Contract *StringsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// StringsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TipsTransactorSession struct { - Contract *TipsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type StringsTransactorSession struct { + Contract *StringsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TipsRaw struct { - Contract *Tips // Generic contract binding to access the raw methods on +// StringsRaw is an auto generated low-level Go binding around an Ethereum contract. +type StringsRaw struct { + Contract *Strings // Generic contract binding to access the raw methods on } -// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TipsCallerRaw struct { - Contract *TipsCaller // Generic read-only contract binding to access the raw methods on +// StringsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type StringsCallerRaw struct { + Contract *StringsCaller // Generic read-only contract binding to access the raw methods on } -// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TipsTransactorRaw struct { - Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on +// StringsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type StringsTransactorRaw struct { + Contract *StringsTransactor // Generic write-only contract binding to access the raw methods on } -// NewTips creates a new instance of Tips, bound to a specific deployed contract. -func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { - contract, err := bindTips(address, backend, backend, backend) +// NewStrings creates a new instance of Strings, bound to a specific deployed contract. +func NewStrings(address common.Address, backend bind.ContractBackend) (*Strings, error) { + contract, err := bindStrings(address, backend, backend, backend) if err != nil { return nil, err } - return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil + return &Strings{StringsCaller: StringsCaller{contract: contract}, StringsTransactor: StringsTransactor{contract: contract}, StringsFilterer: StringsFilterer{contract: contract}}, nil } -// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. -func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { - contract, err := bindTips(address, caller, nil, nil) +// NewStringsCaller creates a new read-only instance of Strings, bound to a specific deployed contract. +func NewStringsCaller(address common.Address, caller bind.ContractCaller) (*StringsCaller, error) { + contract, err := bindStrings(address, caller, nil, nil) if err != nil { return nil, err } - return &TipsCaller{contract: contract}, nil + return &StringsCaller{contract: contract}, nil } -// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. -func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { - contract, err := bindTips(address, nil, transactor, nil) +// NewStringsTransactor creates a new write-only instance of Strings, bound to a specific deployed contract. +func NewStringsTransactor(address common.Address, transactor bind.ContractTransactor) (*StringsTransactor, error) { + contract, err := bindStrings(address, nil, transactor, nil) if err != nil { return nil, err } - return &TipsTransactor{contract: contract}, nil + return &StringsTransactor{contract: contract}, nil } -// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. -func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { - contract, err := bindTips(address, nil, nil, filterer) +// NewStringsFilterer creates a new log filterer instance of Strings, bound to a specific deployed contract. +func NewStringsFilterer(address common.Address, filterer bind.ContractFilterer) (*StringsFilterer, error) { + contract, err := bindStrings(address, nil, nil, filterer) if err != nil { return nil, err } - return &TipsFilterer{contract: contract}, nil + return &StringsFilterer{contract: contract}, nil } -// bindTips binds a generic wrapper to an already deployed contract. -func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TipsABI)) +// bindStrings binds a generic wrapper to an already deployed contract. +func bindStrings(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(StringsABI)) if err != nil { return nil, err } @@ -6360,169 +7822,159 @@ func bindTips(address common.Address, caller bind.ContractCaller, transactor bin // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) +func (_Strings *StringsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Strings.Contract.StringsCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transfer(opts) +func (_Strings *StringsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Strings.Contract.StringsTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) +func (_Strings *StringsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Strings.Contract.StringsTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _Tips.Contract.contract.Call(opts, result, method, params...) +func (_Strings *StringsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Strings.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _Tips.Contract.contract.Transfer(opts) +func (_Strings *StringsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Strings.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _Tips.Contract.contract.Transact(opts, method, params...) +func (_Strings *StringsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Strings.Contract.contract.Transact(opts, method, params...) } -// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. -var TypeCastsMetaData = &bind.MetaData{ - ABI: "[]", - Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220942898ca74b9cab7df55dc078162794c91fd26295ea1119c0f3e854102564e6e64736f6c634300080d0033", +// SystemContractMetaData contains all meta data concerning the SystemContract contract. +var SystemContractMetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "8d3638f4": "localDomain()", + "8da5cb5b": "owner()", + "715018a6": "renounceOwnership()", + "b7bc563e": "setSystemMessenger(address)", + "ccbdf9c9": "systemMessenger()", + "f2fde38b": "transferOwnership(address)", + }, } -// TypeCastsABI is the input ABI used to generate the binding from. -// Deprecated: Use TypeCastsMetaData.ABI instead. -var TypeCastsABI = TypeCastsMetaData.ABI - -// TypeCastsBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypeCastsMetaData.Bin instead. -var TypeCastsBin = TypeCastsMetaData.Bin - -// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. -func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { - parsed, err := TypeCastsMetaData.GetAbi() - if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") - } +// SystemContractABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemContractMetaData.ABI instead. +var SystemContractABI = SystemContractMetaData.ABI - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil -} +// Deprecated: Use SystemContractMetaData.Sigs instead. +// SystemContractFuncSigs maps the 4-byte function signature to its string representation. +var SystemContractFuncSigs = SystemContractMetaData.Sigs -// TypeCasts is an auto generated Go binding around an Ethereum contract. -type TypeCasts struct { - TypeCastsCaller // Read-only binding to the contract - TypeCastsTransactor // Write-only binding to the contract - TypeCastsFilterer // Log filterer for contract events +// SystemContract is an auto generated Go binding around an Ethereum contract. +type SystemContract struct { + SystemContractCaller // Read-only binding to the contract + SystemContractTransactor // Write-only binding to the contract + SystemContractFilterer // Log filterer for contract events } - -// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypeCastsCaller struct { + +// SystemContractCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemContractCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypeCastsTransactor struct { +// SystemContractTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemContractTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypeCastsFilterer struct { +// SystemContractFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemContractFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// TypeCastsSession is an auto generated Go binding around an Ethereum contract, +// SystemContractSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type TypeCastsSession struct { - Contract *TypeCasts // Generic contract binding to set the session for +type SystemContractSession struct { + Contract *SystemContract // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemContractCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type TypeCastsCallerSession struct { - Contract *TypeCastsCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemContractCallerSession struct { + Contract *SystemContractCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemContractTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type TypeCastsTransactorSession struct { - Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemContractTransactorSession struct { + Contract *SystemContractTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypeCastsRaw struct { - Contract *TypeCasts // Generic contract binding to access the raw methods on +// SystemContractRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemContractRaw struct { + Contract *SystemContract // Generic contract binding to access the raw methods on } -// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypeCastsCallerRaw struct { - Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on +// SystemContractCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemContractCallerRaw struct { + Contract *SystemContractCaller // Generic read-only contract binding to access the raw methods on } -// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypeCastsTransactorRaw struct { - Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on +// SystemContractTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemContractTransactorRaw struct { + Contract *SystemContractTransactor // Generic write-only contract binding to access the raw methods on } -// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { - contract, err := bindTypeCasts(address, backend, backend, backend) +// NewSystemContract creates a new instance of SystemContract, bound to a specific deployed contract. +func NewSystemContract(address common.Address, backend bind.ContractBackend) (*SystemContract, error) { + contract, err := bindSystemContract(address, backend, backend, backend) if err != nil { return nil, err } - return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil + return &SystemContract{SystemContractCaller: SystemContractCaller{contract: contract}, SystemContractTransactor: SystemContractTransactor{contract: contract}, SystemContractFilterer: SystemContractFilterer{contract: contract}}, nil } -// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { - contract, err := bindTypeCasts(address, caller, nil, nil) +// NewSystemContractCaller creates a new read-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractCaller(address common.Address, caller bind.ContractCaller) (*SystemContractCaller, error) { + contract, err := bindSystemContract(address, caller, nil, nil) if err != nil { return nil, err } - return &TypeCastsCaller{contract: contract}, nil + return &SystemContractCaller{contract: contract}, nil } -// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { - contract, err := bindTypeCasts(address, nil, transactor, nil) +// NewSystemContractTransactor creates a new write-only instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemContractTransactor, error) { + contract, err := bindSystemContract(address, nil, transactor, nil) if err != nil { return nil, err } - return &TypeCastsTransactor{contract: contract}, nil + return &SystemContractTransactor{contract: contract}, nil } -// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. -func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { - contract, err := bindTypeCasts(address, nil, nil, filterer) +// NewSystemContractFilterer creates a new log filterer instance of SystemContract, bound to a specific deployed contract. +func NewSystemContractFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemContractFilterer, error) { + contract, err := bindSystemContract(address, nil, nil, filterer) if err != nil { return nil, err } - return &TypeCastsFilterer{contract: contract}, nil + return &SystemContractFilterer{contract: contract}, nil } -// bindTypeCasts binds a generic wrapper to an already deployed contract. -func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) +// bindSystemContract binds a generic wrapper to an already deployed contract. +func bindSystemContract(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemContractABI)) if err != nil { return nil, err } @@ -6533,282 +7985,500 @@ func bindTypeCasts(address common.Address, caller bind.ContractCaller, transacto // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.SystemContractCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) +func (_SystemContract *SystemContractRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.SystemContractTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypeCasts.Contract.contract.Call(opts, result, method, params...) +func (_SystemContract *SystemContractCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemContract.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transfer(opts) +func (_SystemContract *SystemContractTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypeCasts.Contract.contract.Transact(opts, method, params...) +func (_SystemContract *SystemContractTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemContract.Contract.contract.Transact(opts, method, params...) } -// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. -var TypedMemViewMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "f26be3fc": "NULL()", - }, - Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220883677a140a1c4dac75b336e45f111be9dbba3c78a5791534cd010e3455215ca64736f6c634300080d0033", +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "localDomain") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + } -// TypedMemViewABI is the input ABI used to generate the binding from. -// Deprecated: Use TypedMemViewMetaData.ABI instead. -var TypedMemViewABI = TypedMemViewMetaData.ABI +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} -// Deprecated: Use TypedMemViewMetaData.Sigs instead. -// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. -var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs +// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. +// +// Solidity: function localDomain() view returns(uint32) +func (_SystemContract *SystemContractCallerSession) LocalDomain() (uint32, error) { + return _SystemContract.Contract.LocalDomain(&_SystemContract.CallOpts) +} -// TypedMemViewBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use TypedMemViewMetaData.Bin instead. -var TypedMemViewBin = TypedMemViewMetaData.Bin +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "owner") -// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. -func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { - parsed, err := TypedMemViewMetaData.GetAbi() if err != nil { - return common.Address{}, nil, nil, err - } - if parsed == nil { - return common.Address{}, nil, nil, errors.New("GetABI returned nil") + return *new(common.Address), err } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_SystemContract *SystemContractCallerSession) Owner() (common.Address, error) { + return _SystemContract.Contract.Owner(&_SystemContract.CallOpts) +} + +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _SystemContract.contract.Call(opts, &out, "systemMessenger") + if err != nil { - return common.Address{}, nil, nil, err + return *new(common.Address), err } - return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + } -// TypedMemView is an auto generated Go binding around an Ethereum contract. -type TypedMemView struct { - TypedMemViewCaller // Read-only binding to the contract - TypedMemViewTransactor // Write-only binding to the contract - TypedMemViewFilterer // Log filterer for contract events +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. -type TypedMemViewCaller struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// +// Solidity: function systemMessenger() view returns(address) +func (_SystemContract *SystemContractCallerSession) SystemMessenger() (common.Address, error) { + return _SystemContract.Contract.SystemMessenger(&_SystemContract.CallOpts) } -// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. -type TypedMemViewTransactor struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "renounceOwnership") } -// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type TypedMemViewFilterer struct { - contract *bind.BoundContract // Generic contract wrapper for the low level calls +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) } -// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, -// with pre-set call and transact options. -type TypedMemViewSession struct { - Contract *TypedMemView // Generic contract binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_SystemContract *SystemContractTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _SystemContract.Contract.RenounceOwnership(&_SystemContract.TransactOpts) } -// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, -// with pre-set call options. -type TypedMemViewCallerSession struct { - Contract *TypedMemViewCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "setSystemMessenger", _systemMessenger) } -// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, -// with pre-set transact options. -type TypedMemViewTransactorSession struct { - Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) } -// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. -type TypedMemViewRaw struct { - Contract *TypedMemView // Generic contract binding to access the raw methods on +// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// +// Solidity: function setSystemMessenger(address _systemMessenger) returns() +func (_SystemContract *SystemContractTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.SetSystemMessenger(&_SystemContract.TransactOpts, _systemMessenger) } -// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type TypedMemViewCallerRaw struct { - Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_SystemContract *SystemContractTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _SystemContract.Contract.TransferOwnership(&_SystemContract.TransactOpts, newOwner) +} + +// SystemContractInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the SystemContract contract. +type SystemContractInitializedIterator struct { + Event *SystemContractInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type TypedMemViewTransactorRaw struct { - Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractInitializedIterator) Error() error { + return it.fail } -// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { - contract, err := bindTypedMemView(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { - contract, err := bindTypedMemView(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &TypedMemViewCaller{contract: contract}, nil +// SystemContractInitialized represents a Initialized event raised by the SystemContract contract. +type SystemContractInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos } -// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { - contract, err := bindTypedMemView(address, nil, transactor, nil) +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) FilterInitialized(opts *bind.FilterOpts) (*SystemContractInitializedIterator, error) { + + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypedMemViewTransactor{contract: contract}, nil + return &SystemContractInitializedIterator{contract: _SystemContract.contract, event: "Initialized", logs: logs, sub: sub}, nil } -// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. -func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { - contract, err := bindTypedMemView(address, nil, nil, filterer) +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *SystemContractInitialized) (event.Subscription, error) { + + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "Initialized") if err != nil { return nil, err } - return &TypedMemViewFilterer{contract: contract}, nil + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// bindTypedMemView binds a generic wrapper to an already deployed contract. -func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) - if err != nil { +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_SystemContract *SystemContractFilterer) ParseInitialized(log types.Log) (*SystemContractInitialized, error) { + event := new(SystemContractInitialized) + if err := _SystemContract.contract.UnpackLog(event, "Initialized", log); err != nil { return nil, err } - return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil + event.Raw = log + return event, nil } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) -} +// SystemContractOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the SystemContract contract. +type SystemContractOwnershipTransferredIterator struct { + Event *SystemContractOwnershipTransferred // Event containing the contract specifics and raw log -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration } -// Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *SystemContractOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(SystemContractOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -// Call invokes the (constant) contract method with params as input values and -// sets the output to result. The result type might be a single field for simple -// returns, a slice of interfaces for anonymous returns and a struct for named -// returns. -func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _TypedMemView.Contract.contract.Call(opts, result, method, params...) +// Error returns any retrieval or parsing error occurred during filtering. +func (it *SystemContractOwnershipTransferredIterator) Error() error { + return it.fail } -// Transfer initiates a plain transaction to move funds to the contract, calling -// its default method if one is available. -func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transfer(opts) +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *SystemContractOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil } -// Transact invokes the (paid) contract method with params as input values. -func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _TypedMemView.Contract.contract.Transact(opts, method, params...) +// SystemContractOwnershipTransferred represents a OwnershipTransferred event raised by the SystemContract contract. +type SystemContractOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { - var out []interface{} - err := _TypedMemView.contract.Call(opts, &out, "NULL") +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*SystemContractOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + logs, sub, err := _SystemContract.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { - return *new([29]byte), err + return nil, err } + return &SystemContractOwnershipTransferredIterator{contract: _SystemContract.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} - out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *SystemContractOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - return out0, err + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } -} + logs, sub, err := _SystemContract.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. -// -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil } -// NULL is a free data retrieval call binding the contract method 0xf26be3fc. +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: function NULL() view returns(bytes29) -func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { - return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) -} - -// UpdaterManagerMetaData contains all meta data concerning the UpdaterManager contract. -var UpdaterManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterAddress\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"FakeSlashed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"home\",\"type\":\"address\"}],\"name\":\"NewHome\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"home\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_home\",\"type\":\"address\"}],\"name\":\"setHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterAddress\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Sigs: map[string]string{ - "9fa92f9d": "home()", - "8da5cb5b": "owner()", - "715018a6": "renounceOwnership()", - "6ef0f37f": "setHome(address)", - "9d54f419": "setUpdater(address)", - "5b3c2cbf": "slashUpdater(address)", - "f2fde38b": "transferOwnership(address)", - "df034cd0": "updater()", - }, - Bin: "0x60806040526040516108a83803806108a8833981016040819052610022916100a0565b61002b33610050565b600280546001600160a01b0319166001600160a01b03929092169190911790556100d0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100b257600080fd5b81516001600160a01b03811681146100c957600080fd5b9392505050565b6107c9806100df6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80639d54f4191161005b5780639d54f419146101005780639fa92f9d14610113578063df034cd014610133578063f2fde38b1461015157600080fd5b80635b3c2cbf1461008d5780636ef0f37f146100a2578063715018a6146100b55780638da5cb5b146100bd575b600080fd5b6100a061009b36600461076f565b610164565b005b6100a06100b036600461076f565b610237565b6100a06103a9565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100a061010e36600461076f565b61042c565b6001546100d79073ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff166100d7565b6100a061015f36600461076f565b6105a8565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f21686f6d6500000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60405173ffffffffffffffffffffffffffffffffffffffff821681527f4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81163b610336576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f21636f6e747261637420686f6d6500000000000000000000000000000000000060448201526064016101e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de219060200161022c565b60005473ffffffffffffffffffffffffffffffffffffffff16331461042a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556001546040517f9d54f419000000000000000000000000000000000000000000000000000000008152600481019290925290911690639d54f41990602401600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681527f9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c329250602001905061022c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81166106cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101e1565b6106d5816106d8565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106d557600080fd5b60006020828403121561078157600080fd5b813561078c8161074d565b939250505056fea2646970667358221220cae6d97d734603030c73ce13d0eac208b8db318b2417b12187666996b512ee8e64736f6c634300080d0033", +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_SystemContract *SystemContractFilterer) ParseOwnershipTransferred(log types.Log) (*SystemContractOwnershipTransferred, error) { + event := new(SystemContractOwnershipTransferred) + if err := _SystemContract.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil } -// UpdaterManagerABI is the input ABI used to generate the binding from. -// Deprecated: Use UpdaterManagerMetaData.ABI instead. -var UpdaterManagerABI = UpdaterManagerMetaData.ABI - -// Deprecated: Use UpdaterManagerMetaData.Sigs instead. -// UpdaterManagerFuncSigs maps the 4-byte function signature to its string representation. -var UpdaterManagerFuncSigs = UpdaterManagerMetaData.Sigs +// SystemMessageMetaData contains all meta data concerning the SystemMessage contract. +var SystemMessageMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122064cd8c626afbf5334bd6d2c4c9a698cd7f253d64ccad6b7ea3294f4c749db02f64736f6c634300080d0033", +} -// UpdaterManagerBin is the compiled bytecode used for deploying new contracts. -// Deprecated: Use UpdaterManagerMetaData.Bin instead. -var UpdaterManagerBin = UpdaterManagerMetaData.Bin +// SystemMessageABI is the input ABI used to generate the binding from. +// Deprecated: Use SystemMessageMetaData.ABI instead. +var SystemMessageABI = SystemMessageMetaData.ABI -// DeployUpdaterManager deploys a new Ethereum contract, binding an instance of UpdaterManager to it. -func DeployUpdaterManager(auth *bind.TransactOpts, backend bind.ContractBackend, _updaterAddress common.Address) (common.Address, *types.Transaction, *UpdaterManager, error) { - parsed, err := UpdaterManagerMetaData.GetAbi() +// SystemMessageBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use SystemMessageMetaData.Bin instead. +var SystemMessageBin = SystemMessageMetaData.Bin + +// DeploySystemMessage deploys a new Ethereum contract, binding an instance of SystemMessage to it. +func DeploySystemMessage(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *SystemMessage, error) { + parsed, err := SystemMessageMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err } @@ -6816,111 +8486,111 @@ func DeployUpdaterManager(auth *bind.TransactOpts, backend bind.ContractBackend, return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(UpdaterManagerBin), backend, _updaterAddress) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(SystemMessageBin), backend) if err != nil { return common.Address{}, nil, nil, err } - return address, tx, &UpdaterManager{UpdaterManagerCaller: UpdaterManagerCaller{contract: contract}, UpdaterManagerTransactor: UpdaterManagerTransactor{contract: contract}, UpdaterManagerFilterer: UpdaterManagerFilterer{contract: contract}}, nil + return address, tx, &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// UpdaterManager is an auto generated Go binding around an Ethereum contract. -type UpdaterManager struct { - UpdaterManagerCaller // Read-only binding to the contract - UpdaterManagerTransactor // Write-only binding to the contract - UpdaterManagerFilterer // Log filterer for contract events +// SystemMessage is an auto generated Go binding around an Ethereum contract. +type SystemMessage struct { + SystemMessageCaller // Read-only binding to the contract + SystemMessageTransactor // Write-only binding to the contract + SystemMessageFilterer // Log filterer for contract events } -// UpdaterManagerCaller is an auto generated read-only Go binding around an Ethereum contract. -type UpdaterManagerCaller struct { +// SystemMessageCaller is an auto generated read-only Go binding around an Ethereum contract. +type SystemMessageCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UpdaterManagerTransactor struct { +// SystemMessageTransactor is an auto generated write-only Go binding around an Ethereum contract. +type SystemMessageTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UpdaterManagerFilterer struct { +// SystemMessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type SystemMessageFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterManagerSession is an auto generated Go binding around an Ethereum contract, +// SystemMessageSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type UpdaterManagerSession struct { - Contract *UpdaterManager // Generic contract binding to set the session for +type SystemMessageSession struct { + Contract *SystemMessage // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// SystemMessageCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type UpdaterManagerCallerSession struct { - Contract *UpdaterManagerCaller // Generic contract caller binding to set the session for - CallOpts bind.CallOpts // Call options to use throughout this session +type SystemMessageCallerSession struct { + Contract *SystemMessageCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// UpdaterManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// SystemMessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type UpdaterManagerTransactorSession struct { - Contract *UpdaterManagerTransactor // Generic contract transactor binding to set the session for - TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +type SystemMessageTransactorSession struct { + Contract *SystemMessageTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterManagerRaw is an auto generated low-level Go binding around an Ethereum contract. -type UpdaterManagerRaw struct { - Contract *UpdaterManager // Generic contract binding to access the raw methods on +// SystemMessageRaw is an auto generated low-level Go binding around an Ethereum contract. +type SystemMessageRaw struct { + Contract *SystemMessage // Generic contract binding to access the raw methods on } -// UpdaterManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UpdaterManagerCallerRaw struct { - Contract *UpdaterManagerCaller // Generic read-only contract binding to access the raw methods on +// SystemMessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type SystemMessageCallerRaw struct { + Contract *SystemMessageCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UpdaterManagerTransactorRaw struct { - Contract *UpdaterManagerTransactor // Generic write-only contract binding to access the raw methods on +// SystemMessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type SystemMessageTransactorRaw struct { + Contract *SystemMessageTransactor // Generic write-only contract binding to access the raw methods on } -// NewUpdaterManager creates a new instance of UpdaterManager, bound to a specific deployed contract. -func NewUpdaterManager(address common.Address, backend bind.ContractBackend) (*UpdaterManager, error) { - contract, err := bindUpdaterManager(address, backend, backend, backend) +// NewSystemMessage creates a new instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessage(address common.Address, backend bind.ContractBackend) (*SystemMessage, error) { + contract, err := bindSystemMessage(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterManager{UpdaterManagerCaller: UpdaterManagerCaller{contract: contract}, UpdaterManagerTransactor: UpdaterManagerTransactor{contract: contract}, UpdaterManagerFilterer: UpdaterManagerFilterer{contract: contract}}, nil + return &SystemMessage{SystemMessageCaller: SystemMessageCaller{contract: contract}, SystemMessageTransactor: SystemMessageTransactor{contract: contract}, SystemMessageFilterer: SystemMessageFilterer{contract: contract}}, nil } -// NewUpdaterManagerCaller creates a new read-only instance of UpdaterManager, bound to a specific deployed contract. -func NewUpdaterManagerCaller(address common.Address, caller bind.ContractCaller) (*UpdaterManagerCaller, error) { - contract, err := bindUpdaterManager(address, caller, nil, nil) +// NewSystemMessageCaller creates a new read-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageCaller(address common.Address, caller bind.ContractCaller) (*SystemMessageCaller, error) { + contract, err := bindSystemMessage(address, caller, nil, nil) if err != nil { return nil, err } - return &UpdaterManagerCaller{contract: contract}, nil + return &SystemMessageCaller{contract: contract}, nil } -// NewUpdaterManagerTransactor creates a new write-only instance of UpdaterManager, bound to a specific deployed contract. -func NewUpdaterManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*UpdaterManagerTransactor, error) { - contract, err := bindUpdaterManager(address, nil, transactor, nil) +// NewSystemMessageTransactor creates a new write-only instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*SystemMessageTransactor, error) { + contract, err := bindSystemMessage(address, nil, transactor, nil) if err != nil { return nil, err } - return &UpdaterManagerTransactor{contract: contract}, nil + return &SystemMessageTransactor{contract: contract}, nil } -// NewUpdaterManagerFilterer creates a new log filterer instance of UpdaterManager, bound to a specific deployed contract. -func NewUpdaterManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*UpdaterManagerFilterer, error) { - contract, err := bindUpdaterManager(address, nil, nil, filterer) +// NewSystemMessageFilterer creates a new log filterer instance of SystemMessage, bound to a specific deployed contract. +func NewSystemMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*SystemMessageFilterer, error) { + contract, err := bindSystemMessage(address, nil, nil, filterer) if err != nil { return nil, err } - return &UpdaterManagerFilterer{contract: contract}, nil + return &SystemMessageFilterer{contract: contract}, nil } -// bindUpdaterManager binds a generic wrapper to an already deployed contract. -func bindUpdaterManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(UpdaterManagerABI)) +// bindSystemMessage binds a generic wrapper to an already deployed contract. +func bindSystemMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(SystemMessageABI)) if err != nil { return nil, err } @@ -6931,913 +8601,740 @@ func bindUpdaterManager(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterManager *UpdaterManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterManager.Contract.UpdaterManagerCaller.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.SystemMessageCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterManager *UpdaterManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterManager.Contract.UpdaterManagerTransactor.contract.Transfer(opts) +func (_SystemMessage *SystemMessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterManager *UpdaterManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterManager.Contract.UpdaterManagerTransactor.contract.Transact(opts, method, params...) +func (_SystemMessage *SystemMessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.SystemMessageTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterManager *UpdaterManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterManager.Contract.contract.Call(opts, result, method, params...) +func (_SystemMessage *SystemMessageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _SystemMessage.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterManager *UpdaterManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterManager.Contract.contract.Transfer(opts) +func (_SystemMessage *SystemMessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterManager *UpdaterManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterManager.Contract.contract.Transact(opts, method, params...) -} - -// Home is a free data retrieval call binding the contract method 0x9fa92f9d. -// -// Solidity: function home() view returns(address) -func (_UpdaterManager *UpdaterManagerCaller) Home(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterManager.contract.Call(opts, &out, "home") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - +func (_SystemMessage *SystemMessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _SystemMessage.Contract.contract.Transact(opts, method, params...) } -// Home is a free data retrieval call binding the contract method 0x9fa92f9d. -// -// Solidity: function home() view returns(address) -func (_UpdaterManager *UpdaterManagerSession) Home() (common.Address, error) { - return _UpdaterManager.Contract.Home(&_UpdaterManager.CallOpts) +// TipsMetaData contains all meta data concerning the Tips contract. +var TipsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d07e57f721e4163786684280338d56a69cdc5b67a4bc383ddc24c0064b7b8b2664736f6c634300080d0033", } -// Home is a free data retrieval call binding the contract method 0x9fa92f9d. -// -// Solidity: function home() view returns(address) -func (_UpdaterManager *UpdaterManagerCallerSession) Home() (common.Address, error) { - return _UpdaterManager.Contract.Home(&_UpdaterManager.CallOpts) -} +// TipsABI is the input ABI used to generate the binding from. +// Deprecated: Use TipsMetaData.ABI instead. +var TipsABI = TipsMetaData.ABI -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterManager *UpdaterManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterManager.contract.Call(opts, &out, "owner") +// TipsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TipsMetaData.Bin instead. +var TipsBin = TipsMetaData.Bin +// DeployTips deploys a new Ethereum contract, binding an instance of Tips to it. +func DeployTips(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Tips, error) { + parsed, err := TipsMetaData.GetAbi() if err != nil { - return *new(common.Address), err + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TipsBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterManager *UpdaterManagerSession) Owner() (common.Address, error) { - return _UpdaterManager.Contract.Owner(&_UpdaterManager.CallOpts) +// Tips is an auto generated Go binding around an Ethereum contract. +type Tips struct { + TipsCaller // Read-only binding to the contract + TipsTransactor // Write-only binding to the contract + TipsFilterer // Log filterer for contract events } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. -// -// Solidity: function owner() view returns(address) -func (_UpdaterManager *UpdaterManagerCallerSession) Owner() (common.Address, error) { - return _UpdaterManager.Contract.Owner(&_UpdaterManager.CallOpts) +// TipsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TipsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterManager *UpdaterManagerCaller) Updater(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _UpdaterManager.contract.Call(opts, &out, "updater") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) +// TipsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TipsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - return out0, err +// TipsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TipsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} +// TipsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TipsSession struct { + Contract *Tips // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterManager *UpdaterManagerSession) Updater() (common.Address, error) { - return _UpdaterManager.Contract.Updater(&_UpdaterManager.CallOpts) +// TipsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TipsCallerSession struct { + Contract *TipsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// Updater is a free data retrieval call binding the contract method 0xdf034cd0. -// -// Solidity: function updater() view returns(address) -func (_UpdaterManager *UpdaterManagerCallerSession) Updater() (common.Address, error) { - return _UpdaterManager.Contract.Updater(&_UpdaterManager.CallOpts) +// TipsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TipsTransactorSession struct { + Contract *TipsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterManager *UpdaterManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterManager.contract.Transact(opts, "renounceOwnership") +// TipsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TipsRaw struct { + Contract *Tips // Generic contract binding to access the raw methods on } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterManager *UpdaterManagerSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterManager.Contract.RenounceOwnership(&_UpdaterManager.TransactOpts) +// TipsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TipsCallerRaw struct { + Contract *TipsCaller // Generic read-only contract binding to access the raw methods on } -// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. -// -// Solidity: function renounceOwnership() returns() -func (_UpdaterManager *UpdaterManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterManager.Contract.RenounceOwnership(&_UpdaterManager.TransactOpts) +// TipsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TipsTransactorRaw struct { + Contract *TipsTransactor // Generic write-only contract binding to access the raw methods on } -// SetHome is a paid mutator transaction binding the contract method 0x6ef0f37f. -// -// Solidity: function setHome(address _home) returns() -func (_UpdaterManager *UpdaterManagerTransactor) SetHome(opts *bind.TransactOpts, _home common.Address) (*types.Transaction, error) { - return _UpdaterManager.contract.Transact(opts, "setHome", _home) +// NewTips creates a new instance of Tips, bound to a specific deployed contract. +func NewTips(address common.Address, backend bind.ContractBackend) (*Tips, error) { + contract, err := bindTips(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Tips{TipsCaller: TipsCaller{contract: contract}, TipsTransactor: TipsTransactor{contract: contract}, TipsFilterer: TipsFilterer{contract: contract}}, nil } -// SetHome is a paid mutator transaction binding the contract method 0x6ef0f37f. -// -// Solidity: function setHome(address _home) returns() -func (_UpdaterManager *UpdaterManagerSession) SetHome(_home common.Address) (*types.Transaction, error) { - return _UpdaterManager.Contract.SetHome(&_UpdaterManager.TransactOpts, _home) +// NewTipsCaller creates a new read-only instance of Tips, bound to a specific deployed contract. +func NewTipsCaller(address common.Address, caller bind.ContractCaller) (*TipsCaller, error) { + contract, err := bindTips(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TipsCaller{contract: contract}, nil } -// SetHome is a paid mutator transaction binding the contract method 0x6ef0f37f. -// -// Solidity: function setHome(address _home) returns() -func (_UpdaterManager *UpdaterManagerTransactorSession) SetHome(_home common.Address) (*types.Transaction, error) { - return _UpdaterManager.Contract.SetHome(&_UpdaterManager.TransactOpts, _home) +// NewTipsTransactor creates a new write-only instance of Tips, bound to a specific deployed contract. +func NewTipsTransactor(address common.Address, transactor bind.ContractTransactor) (*TipsTransactor, error) { + contract, err := bindTips(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TipsTransactor{contract: contract}, nil } -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updaterAddress) returns() -func (_UpdaterManager *UpdaterManagerTransactor) SetUpdater(opts *bind.TransactOpts, _updaterAddress common.Address) (*types.Transaction, error) { - return _UpdaterManager.contract.Transact(opts, "setUpdater", _updaterAddress) +// NewTipsFilterer creates a new log filterer instance of Tips, bound to a specific deployed contract. +func NewTipsFilterer(address common.Address, filterer bind.ContractFilterer) (*TipsFilterer, error) { + contract, err := bindTips(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TipsFilterer{contract: contract}, nil } -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updaterAddress) returns() -func (_UpdaterManager *UpdaterManagerSession) SetUpdater(_updaterAddress common.Address) (*types.Transaction, error) { - return _UpdaterManager.Contract.SetUpdater(&_UpdaterManager.TransactOpts, _updaterAddress) +// bindTips binds a generic wrapper to an already deployed contract. +func bindTips(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TipsABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil } -// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. -// -// Solidity: function setUpdater(address _updaterAddress) returns() -func (_UpdaterManager *UpdaterManagerTransactorSession) SetUpdater(_updaterAddress common.Address) (*types.Transaction, error) { - return _UpdaterManager.Contract.SetUpdater(&_UpdaterManager.TransactOpts, _updaterAddress) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Tips *TipsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.TipsCaller.contract.Call(opts, result, method, params...) } -// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. -// -// Solidity: function slashUpdater(address _reporter) returns() -func (_UpdaterManager *UpdaterManagerTransactor) SlashUpdater(opts *bind.TransactOpts, _reporter common.Address) (*types.Transaction, error) { - return _UpdaterManager.contract.Transact(opts, "slashUpdater", _reporter) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Tips *TipsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transfer(opts) } -// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. -// -// Solidity: function slashUpdater(address _reporter) returns() -func (_UpdaterManager *UpdaterManagerSession) SlashUpdater(_reporter common.Address) (*types.Transaction, error) { - return _UpdaterManager.Contract.SlashUpdater(&_UpdaterManager.TransactOpts, _reporter) +// Transact invokes the (paid) contract method with params as input values. +func (_Tips *TipsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.TipsTransactor.contract.Transact(opts, method, params...) } -// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. -// -// Solidity: function slashUpdater(address _reporter) returns() -func (_UpdaterManager *UpdaterManagerTransactorSession) SlashUpdater(_reporter common.Address) (*types.Transaction, error) { - return _UpdaterManager.Contract.SlashUpdater(&_UpdaterManager.TransactOpts, _reporter) +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Tips *TipsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Tips.Contract.contract.Call(opts, result, method, params...) } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterManager *UpdaterManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _UpdaterManager.contract.Transact(opts, "transferOwnership", newOwner) +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Tips *TipsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Tips.Contract.contract.Transfer(opts) } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterManager *UpdaterManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterManager.Contract.TransferOwnership(&_UpdaterManager.TransactOpts, newOwner) +// Transact invokes the (paid) contract method with params as input values. +func (_Tips *TipsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Tips.Contract.contract.Transact(opts, method, params...) } -// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. -// -// Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterManager *UpdaterManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterManager.Contract.TransferOwnership(&_UpdaterManager.TransactOpts, newOwner) +// TypeCastsMetaData contains all meta data concerning the TypeCasts contract. +var TypeCastsMetaData = &bind.MetaData{ + ABI: "[]", + Bin: "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209a36b1ab0276d65052fa22a7df87ebbfa5bab351f13482975564e8f1eced2f2864736f6c634300080d0033", } -// UpdaterManagerFakeSlashedIterator is returned from FilterFakeSlashed and is used to iterate over the raw logs and unpacked data for FakeSlashed events raised by the UpdaterManager contract. -type UpdaterManagerFakeSlashedIterator struct { - Event *UpdaterManagerFakeSlashed // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// TypeCastsABI is the input ABI used to generate the binding from. +// Deprecated: Use TypeCastsMetaData.ABI instead. +var TypeCastsABI = TypeCastsMetaData.ABI - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} +// TypeCastsBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypeCastsMetaData.Bin instead. +var TypeCastsBin = TypeCastsMetaData.Bin -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterManagerFakeSlashedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// DeployTypeCasts deploys a new Ethereum contract, binding an instance of TypeCasts to it. +func DeployTypeCasts(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypeCasts, error) { + parsed, err := TypeCastsMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterManagerFakeSlashed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterManagerFakeSlashed) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypeCastsBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } + return address, tx, &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil +} + +// TypeCasts is an auto generated Go binding around an Ethereum contract. +type TypeCasts struct { + TypeCastsCaller // Read-only binding to the contract + TypeCastsTransactor // Write-only binding to the contract + TypeCastsFilterer // Log filterer for contract events +} + +// TypeCastsCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypeCastsCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TypeCastsTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypeCastsTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TypeCastsFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypeCastsFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TypeCastsSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypeCastsSession struct { + Contract *TypeCasts // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterManagerFakeSlashedIterator) Error() error { - return it.fail +// TypeCastsCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypeCastsCallerSession struct { + Contract *TypeCastsCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterManagerFakeSlashedIterator) Close() error { - it.sub.Unsubscribe() - return nil +// TypeCastsTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypeCastsTransactorSession struct { + Contract *TypeCastsTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterManagerFakeSlashed represents a FakeSlashed event raised by the UpdaterManager contract. -type UpdaterManagerFakeSlashed struct { - Reporter common.Address - Raw types.Log // Blockchain specific contextual infos +// TypeCastsRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypeCastsRaw struct { + Contract *TypeCasts // Generic contract binding to access the raw methods on } -// FilterFakeSlashed is a free log retrieval operation binding the contract event 0x4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f. -// -// Solidity: event FakeSlashed(address reporter) -func (_UpdaterManager *UpdaterManagerFilterer) FilterFakeSlashed(opts *bind.FilterOpts) (*UpdaterManagerFakeSlashedIterator, error) { +// TypeCastsCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypeCastsCallerRaw struct { + Contract *TypeCastsCaller // Generic read-only contract binding to access the raw methods on +} - logs, sub, err := _UpdaterManager.contract.FilterLogs(opts, "FakeSlashed") +// TypeCastsTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypeCastsTransactorRaw struct { + Contract *TypeCastsTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTypeCasts creates a new instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCasts(address common.Address, backend bind.ContractBackend) (*TypeCasts, error) { + contract, err := bindTypeCasts(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterManagerFakeSlashedIterator{contract: _UpdaterManager.contract, event: "FakeSlashed", logs: logs, sub: sub}, nil + return &TypeCasts{TypeCastsCaller: TypeCastsCaller{contract: contract}, TypeCastsTransactor: TypeCastsTransactor{contract: contract}, TypeCastsFilterer: TypeCastsFilterer{contract: contract}}, nil } -// WatchFakeSlashed is a free log subscription operation binding the contract event 0x4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f. -// -// Solidity: event FakeSlashed(address reporter) -func (_UpdaterManager *UpdaterManagerFilterer) WatchFakeSlashed(opts *bind.WatchOpts, sink chan<- *UpdaterManagerFakeSlashed) (event.Subscription, error) { - - logs, sub, err := _UpdaterManager.contract.WatchLogs(opts, "FakeSlashed") +// NewTypeCastsCaller creates a new read-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsCaller(address common.Address, caller bind.ContractCaller) (*TypeCastsCaller, error) { + contract, err := bindTypeCasts(address, caller, nil, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterManagerFakeSlashed) - if err := _UpdaterManager.contract.UnpackLog(event, "FakeSlashed", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypeCastsCaller{contract: contract}, nil } -// ParseFakeSlashed is a log parse operation binding the contract event 0x4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f. -// -// Solidity: event FakeSlashed(address reporter) -func (_UpdaterManager *UpdaterManagerFilterer) ParseFakeSlashed(log types.Log) (*UpdaterManagerFakeSlashed, error) { - event := new(UpdaterManagerFakeSlashed) - if err := _UpdaterManager.contract.UnpackLog(event, "FakeSlashed", log); err != nil { +// NewTypeCastsTransactor creates a new write-only instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsTransactor(address common.Address, transactor bind.ContractTransactor) (*TypeCastsTransactor, error) { + contract, err := bindTypeCasts(address, nil, transactor, nil) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &TypeCastsTransactor{contract: contract}, nil } -// UpdaterManagerNewHomeIterator is returned from FilterNewHome and is used to iterate over the raw logs and unpacked data for NewHome events raised by the UpdaterManager contract. -type UpdaterManagerNewHomeIterator struct { - Event *UpdaterManagerNewHome // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// NewTypeCastsFilterer creates a new log filterer instance of TypeCasts, bound to a specific deployed contract. +func NewTypeCastsFilterer(address common.Address, filterer bind.ContractFilterer) (*TypeCastsFilterer, error) { + contract, err := bindTypeCasts(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TypeCastsFilterer{contract: contract}, nil } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterManagerNewHomeIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// bindTypeCasts binds a generic wrapper to an already deployed contract. +func bindTypeCasts(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypeCastsABI)) + if err != nil { + return nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterManagerNewHome) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterManagerNewHome) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.TypeCastsCaller.contract.Call(opts, result, method, params...) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transfer(opts) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterManagerNewHomeIterator) Error() error { - return it.fail +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.TypeCastsTransactor.contract.Transact(opts, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterManagerNewHomeIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypeCasts *TypeCastsCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypeCasts.Contract.contract.Call(opts, result, method, params...) } -// UpdaterManagerNewHome represents a NewHome event raised by the UpdaterManager contract. -type UpdaterManagerNewHome struct { - Home common.Address - Raw types.Log // Blockchain specific contextual infos +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypeCasts *TypeCastsTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transfer(opts) } -// FilterNewHome is a free log retrieval operation binding the contract event 0xa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de21. -// -// Solidity: event NewHome(address home) -func (_UpdaterManager *UpdaterManagerFilterer) FilterNewHome(opts *bind.FilterOpts) (*UpdaterManagerNewHomeIterator, error) { +// Transact invokes the (paid) contract method with params as input values. +func (_TypeCasts *TypeCastsTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypeCasts.Contract.contract.Transact(opts, method, params...) +} - logs, sub, err := _UpdaterManager.contract.FilterLogs(opts, "NewHome") - if err != nil { - return nil, err - } - return &UpdaterManagerNewHomeIterator{contract: _UpdaterManager.contract, event: "NewHome", logs: logs, sub: sub}, nil +// TypedMemViewMetaData contains all meta data concerning the TypedMemView contract. +var TypedMemViewMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Sigs: map[string]string{ + "f26be3fc": "NULL()", + }, + Bin: "0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220fc0648112c9392b6186c78f34911f5cd0662b794e868bd97e8300d36afbfb81464736f6c634300080d0033", } -// WatchNewHome is a free log subscription operation binding the contract event 0xa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de21. -// -// Solidity: event NewHome(address home) -func (_UpdaterManager *UpdaterManagerFilterer) WatchNewHome(opts *bind.WatchOpts, sink chan<- *UpdaterManagerNewHome) (event.Subscription, error) { +// TypedMemViewABI is the input ABI used to generate the binding from. +// Deprecated: Use TypedMemViewMetaData.ABI instead. +var TypedMemViewABI = TypedMemViewMetaData.ABI - logs, sub, err := _UpdaterManager.contract.WatchLogs(opts, "NewHome") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterManagerNewHome) - if err := _UpdaterManager.contract.UnpackLog(event, "NewHome", log); err != nil { - return err - } - event.Raw = log +// Deprecated: Use TypedMemViewMetaData.Sigs instead. +// TypedMemViewFuncSigs maps the 4-byte function signature to its string representation. +var TypedMemViewFuncSigs = TypedMemViewMetaData.Sigs - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} +// TypedMemViewBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TypedMemViewMetaData.Bin instead. +var TypedMemViewBin = TypedMemViewMetaData.Bin + +// DeployTypedMemView deploys a new Ethereum contract, binding an instance of TypedMemView to it. +func DeployTypedMemView(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *TypedMemView, error) { + parsed, err := TypedMemViewMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } -// ParseNewHome is a log parse operation binding the contract event 0xa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de21. -// -// Solidity: event NewHome(address home) -func (_UpdaterManager *UpdaterManagerFilterer) ParseNewHome(log types.Log) (*UpdaterManagerNewHome, error) { - event := new(UpdaterManagerNewHome) - if err := _UpdaterManager.contract.UnpackLog(event, "NewHome", log); err != nil { - return nil, err + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TypedMemViewBin), backend) + if err != nil { + return common.Address{}, nil, nil, err } - event.Raw = log - return event, nil + return address, tx, &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil } -// UpdaterManagerNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the UpdaterManager contract. -type UpdaterManagerNewUpdaterIterator struct { - Event *UpdaterManagerNewUpdater // Event containing the contract specifics and raw log +// TypedMemView is an auto generated Go binding around an Ethereum contract. +type TypedMemView struct { + TypedMemViewCaller // Read-only binding to the contract + TypedMemViewTransactor // Write-only binding to the contract + TypedMemViewFilterer // Log filterer for contract events +} - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data +// TypedMemViewCaller is an auto generated read-only Go binding around an Ethereum contract. +type TypedMemViewCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// TypedMemViewTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TypedMemViewTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterManagerNewUpdaterIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterManagerNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TypedMemViewFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterManagerNewUpdater) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// TypedMemViewSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TypedMemViewSession struct { + Contract *TypedMemView // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// TypedMemViewCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TypedMemViewCallerSession struct { + Contract *TypedMemViewCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterManagerNewUpdaterIterator) Error() error { - return it.fail +// TypedMemViewTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TypedMemViewTransactorSession struct { + Contract *TypedMemViewTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterManagerNewUpdaterIterator) Close() error { - it.sub.Unsubscribe() - return nil +// TypedMemViewRaw is an auto generated low-level Go binding around an Ethereum contract. +type TypedMemViewRaw struct { + Contract *TypedMemView // Generic contract binding to access the raw methods on } -// UpdaterManagerNewUpdater represents a NewUpdater event raised by the UpdaterManager contract. -type UpdaterManagerNewUpdater struct { - Updater common.Address - Raw types.Log // Blockchain specific contextual infos +// TypedMemViewCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TypedMemViewCallerRaw struct { + Contract *TypedMemViewCaller // Generic read-only contract binding to access the raw methods on } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c32. -// -// Solidity: event NewUpdater(address updater) -func (_UpdaterManager *UpdaterManagerFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*UpdaterManagerNewUpdaterIterator, error) { +// TypedMemViewTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TypedMemViewTransactorRaw struct { + Contract *TypedMemViewTransactor // Generic write-only contract binding to access the raw methods on +} - logs, sub, err := _UpdaterManager.contract.FilterLogs(opts, "NewUpdater") +// NewTypedMemView creates a new instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemView(address common.Address, backend bind.ContractBackend) (*TypedMemView, error) { + contract, err := bindTypedMemView(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterManagerNewUpdaterIterator{contract: _UpdaterManager.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &TypedMemView{TypedMemViewCaller: TypedMemViewCaller{contract: contract}, TypedMemViewTransactor: TypedMemViewTransactor{contract: contract}, TypedMemViewFilterer: TypedMemViewFilterer{contract: contract}}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c32. -// -// Solidity: event NewUpdater(address updater) -func (_UpdaterManager *UpdaterManagerFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *UpdaterManagerNewUpdater) (event.Subscription, error) { - - logs, sub, err := _UpdaterManager.contract.WatchLogs(opts, "NewUpdater") +// NewTypedMemViewCaller creates a new read-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewCaller(address common.Address, caller bind.ContractCaller) (*TypedMemViewCaller, error) { + contract, err := bindTypedMemView(address, caller, nil, nil) if err != nil { return nil, err } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterManagerNewUpdater) - if err := _UpdaterManager.contract.UnpackLog(event, "NewUpdater", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil + return &TypedMemViewCaller{contract: contract}, nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c32. -// -// Solidity: event NewUpdater(address updater) -func (_UpdaterManager *UpdaterManagerFilterer) ParseNewUpdater(log types.Log) (*UpdaterManagerNewUpdater, error) { - event := new(UpdaterManagerNewUpdater) - if err := _UpdaterManager.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// NewTypedMemViewTransactor creates a new write-only instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewTransactor(address common.Address, transactor bind.ContractTransactor) (*TypedMemViewTransactor, error) { + contract, err := bindTypedMemView(address, nil, transactor, nil) + if err != nil { return nil, err } - event.Raw = log - return event, nil + return &TypedMemViewTransactor{contract: contract}, nil } -// UpdaterManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UpdaterManager contract. -type UpdaterManagerOwnershipTransferredIterator struct { - Event *UpdaterManagerOwnershipTransferred // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration +// NewTypedMemViewFilterer creates a new log filterer instance of TypedMemView, bound to a specific deployed contract. +func NewTypedMemViewFilterer(address common.Address, filterer bind.ContractFilterer) (*TypedMemViewFilterer, error) { + contract, err := bindTypedMemView(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TypedMemViewFilterer{contract: contract}, nil } -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *UpdaterManagerOwnershipTransferredIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false +// bindTypedMemView binds a generic wrapper to an already deployed contract. +func bindTypedMemView(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(TypedMemViewABI)) + if err != nil { + return nil, err } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(UpdaterManagerOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(UpdaterManagerOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.TypedMemViewCaller.contract.Call(opts, result, method, params...) +} - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.TypedMemViewTransactor.contract.Transact(opts, method, params...) } -// Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterManagerOwnershipTransferredIterator) Error() error { - return it.fail +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TypedMemView *TypedMemViewCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TypedMemView.Contract.contract.Call(opts, result, method, params...) } -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *UpdaterManagerOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TypedMemView *TypedMemViewTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transfer(opts) } -// UpdaterManagerOwnershipTransferred represents a OwnershipTransferred event raised by the UpdaterManager contract. -type UpdaterManagerOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// Transact invokes the (paid) contract method with params as input values. +func (_TypedMemView *TypedMemViewTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TypedMemView.Contract.contract.Transact(opts, method, params...) } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterManager *UpdaterManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UpdaterManagerOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCaller) NULL(opts *bind.CallOpts) ([29]byte, error) { + var out []interface{} + err := _TypedMemView.contract.Call(opts, &out, "NULL") - logs, sub, err := _UpdaterManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { - return nil, err + return *new([29]byte), err } - return &UpdaterManagerOwnershipTransferredIterator{contract: _UpdaterManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. -// -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterManager *UpdaterManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UpdaterManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + out0 := *abi.ConvertType(out[0], new([29]byte)).(*[29]byte) - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } + return out0, err - logs, sub, err := _UpdaterManager.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(UpdaterManagerOwnershipTransferred) - if err := _UpdaterManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return err - } - event.Raw = log +} - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. +// +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// NULL is a free data retrieval call binding the contract method 0xf26be3fc. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterManager *UpdaterManagerFilterer) ParseOwnershipTransferred(log types.Log) (*UpdaterManagerOwnershipTransferred, error) { - event := new(UpdaterManagerOwnershipTransferred) - if err := _UpdaterManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil +// Solidity: function NULL() view returns(bytes29) +func (_TypedMemView *TypedMemViewCallerSession) NULL() ([29]byte, error) { + return _TypedMemView.Contract.NULL(&_TypedMemView.CallOpts) } -// UpdaterStorageMetaData contains all meta data concerning the UpdaterStorage contract. -var UpdaterStorageMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contractISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +// UpdaterManagerMetaData contains all meta data concerning the UpdaterManager contract. +var UpdaterManagerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterAddress\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"FakeSlashed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"home\",\"type\":\"address\"}],\"name\":\"NewHome\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"home\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_home\",\"type\":\"address\"}],\"name\":\"setHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterAddress\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", Sigs: map[string]string{ - "8d3638f4": "localDomain()", + "9fa92f9d": "home()", "8da5cb5b": "owner()", "715018a6": "renounceOwnership()", - "b7bc563e": "setSystemMessenger(address)", - "ccbdf9c9": "systemMessenger()", + "6ef0f37f": "setHome(address)", + "9d54f419": "setUpdater(address)", + "5b3c2cbf": "slashUpdater(address)", "f2fde38b": "transferOwnership(address)", "df034cd0": "updater()", }, + Bin: "0x60806040526040516108a83803806108a8833981016040819052610022916100a0565b61002b33610050565b600280546001600160a01b0319166001600160a01b03929092169190911790556100d0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100b257600080fd5b81516001600160a01b03811681146100c957600080fd5b9392505050565b6107c9806100df6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80639d54f4191161005b5780639d54f419146101005780639fa92f9d14610113578063df034cd014610133578063f2fde38b1461015157600080fd5b80635b3c2cbf1461008d5780636ef0f37f146100a2578063715018a6146100b55780638da5cb5b146100bd575b600080fd5b6100a061009b36600461076f565b610164565b005b6100a06100b036600461076f565b610237565b6100a06103a9565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100a061010e36600461076f565b61042c565b6001546100d79073ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff166100d7565b6100a061015f36600461076f565b6105a8565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f21686f6d6500000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60405173ffffffffffffffffffffffffffffffffffffffff821681527f4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81163b610336576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f21636f6e747261637420686f6d6500000000000000000000000000000000000060448201526064016101e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de219060200161022c565b60005473ffffffffffffffffffffffffffffffffffffffff16331461042a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556001546040517f9d54f419000000000000000000000000000000000000000000000000000000008152600481019290925290911690639d54f41990602401600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681527f9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c329250602001905061022c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81166106cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101e1565b6106d5816106d8565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106d557600080fd5b60006020828403121561078157600080fd5b813561078c8161074d565b939250505056fea2646970667358221220333c3411f3fb78827ee9c4ed7dac81c513db0b8e6d2dab91e42599d68c45683c64736f6c634300080d0033", } -// UpdaterStorageABI is the input ABI used to generate the binding from. -// Deprecated: Use UpdaterStorageMetaData.ABI instead. -var UpdaterStorageABI = UpdaterStorageMetaData.ABI +// UpdaterManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use UpdaterManagerMetaData.ABI instead. +var UpdaterManagerABI = UpdaterManagerMetaData.ABI + +// Deprecated: Use UpdaterManagerMetaData.Sigs instead. +// UpdaterManagerFuncSigs maps the 4-byte function signature to its string representation. +var UpdaterManagerFuncSigs = UpdaterManagerMetaData.Sigs + +// UpdaterManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use UpdaterManagerMetaData.Bin instead. +var UpdaterManagerBin = UpdaterManagerMetaData.Bin + +// DeployUpdaterManager deploys a new Ethereum contract, binding an instance of UpdaterManager to it. +func DeployUpdaterManager(auth *bind.TransactOpts, backend bind.ContractBackend, _updaterAddress common.Address) (common.Address, *types.Transaction, *UpdaterManager, error) { + parsed, err := UpdaterManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } -// Deprecated: Use UpdaterStorageMetaData.Sigs instead. -// UpdaterStorageFuncSigs maps the 4-byte function signature to its string representation. -var UpdaterStorageFuncSigs = UpdaterStorageMetaData.Sigs + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(UpdaterManagerBin), backend, _updaterAddress) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &UpdaterManager{UpdaterManagerCaller: UpdaterManagerCaller{contract: contract}, UpdaterManagerTransactor: UpdaterManagerTransactor{contract: contract}, UpdaterManagerFilterer: UpdaterManagerFilterer{contract: contract}}, nil +} -// UpdaterStorage is an auto generated Go binding around an Ethereum contract. -type UpdaterStorage struct { - UpdaterStorageCaller // Read-only binding to the contract - UpdaterStorageTransactor // Write-only binding to the contract - UpdaterStorageFilterer // Log filterer for contract events +// UpdaterManager is an auto generated Go binding around an Ethereum contract. +type UpdaterManager struct { + UpdaterManagerCaller // Read-only binding to the contract + UpdaterManagerTransactor // Write-only binding to the contract + UpdaterManagerFilterer // Log filterer for contract events } -// UpdaterStorageCaller is an auto generated read-only Go binding around an Ethereum contract. -type UpdaterStorageCaller struct { +// UpdaterManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type UpdaterManagerCaller struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageTransactor is an auto generated write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactor struct { +// UpdaterManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type UpdaterManagerTransactor struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageFilterer is an auto generated log filtering Go binding around an Ethereum contract events. -type UpdaterStorageFilterer struct { +// UpdaterManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type UpdaterManagerFilterer struct { contract *bind.BoundContract // Generic contract wrapper for the low level calls } -// UpdaterStorageSession is an auto generated Go binding around an Ethereum contract, +// UpdaterManagerSession is an auto generated Go binding around an Ethereum contract, // with pre-set call and transact options. -type UpdaterStorageSession struct { - Contract *UpdaterStorage // Generic contract binding to set the session for +type UpdaterManagerSession struct { + Contract *UpdaterManager // Generic contract binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// UpdaterManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, // with pre-set call options. -type UpdaterStorageCallerSession struct { - Contract *UpdaterStorageCaller // Generic contract caller binding to set the session for +type UpdaterManagerCallerSession struct { + Contract *UpdaterManagerCaller // Generic contract caller binding to set the session for CallOpts bind.CallOpts // Call options to use throughout this session } -// UpdaterStorageTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// UpdaterManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, // with pre-set transact options. -type UpdaterStorageTransactorSession struct { - Contract *UpdaterStorageTransactor // Generic contract transactor binding to set the session for +type UpdaterManagerTransactorSession struct { + Contract *UpdaterManagerTransactor // Generic contract transactor binding to set the session for TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session } -// UpdaterStorageRaw is an auto generated low-level Go binding around an Ethereum contract. -type UpdaterStorageRaw struct { - Contract *UpdaterStorage // Generic contract binding to access the raw methods on +// UpdaterManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type UpdaterManagerRaw struct { + Contract *UpdaterManager // Generic contract binding to access the raw methods on } -// UpdaterStorageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. -type UpdaterStorageCallerRaw struct { - Contract *UpdaterStorageCaller // Generic read-only contract binding to access the raw methods on +// UpdaterManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type UpdaterManagerCallerRaw struct { + Contract *UpdaterManagerCaller // Generic read-only contract binding to access the raw methods on } -// UpdaterStorageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. -type UpdaterStorageTransactorRaw struct { - Contract *UpdaterStorageTransactor // Generic write-only contract binding to access the raw methods on +// UpdaterManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type UpdaterManagerTransactorRaw struct { + Contract *UpdaterManagerTransactor // Generic write-only contract binding to access the raw methods on } -// NewUpdaterStorage creates a new instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorage(address common.Address, backend bind.ContractBackend) (*UpdaterStorage, error) { - contract, err := bindUpdaterStorage(address, backend, backend, backend) +// NewUpdaterManager creates a new instance of UpdaterManager, bound to a specific deployed contract. +func NewUpdaterManager(address common.Address, backend bind.ContractBackend) (*UpdaterManager, error) { + contract, err := bindUpdaterManager(address, backend, backend, backend) if err != nil { return nil, err } - return &UpdaterStorage{UpdaterStorageCaller: UpdaterStorageCaller{contract: contract}, UpdaterStorageTransactor: UpdaterStorageTransactor{contract: contract}, UpdaterStorageFilterer: UpdaterStorageFilterer{contract: contract}}, nil + return &UpdaterManager{UpdaterManagerCaller: UpdaterManagerCaller{contract: contract}, UpdaterManagerTransactor: UpdaterManagerTransactor{contract: contract}, UpdaterManagerFilterer: UpdaterManagerFilterer{contract: contract}}, nil } -// NewUpdaterStorageCaller creates a new read-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageCaller(address common.Address, caller bind.ContractCaller) (*UpdaterStorageCaller, error) { - contract, err := bindUpdaterStorage(address, caller, nil, nil) +// NewUpdaterManagerCaller creates a new read-only instance of UpdaterManager, bound to a specific deployed contract. +func NewUpdaterManagerCaller(address common.Address, caller bind.ContractCaller) (*UpdaterManagerCaller, error) { + contract, err := bindUpdaterManager(address, caller, nil, nil) if err != nil { return nil, err } - return &UpdaterStorageCaller{contract: contract}, nil + return &UpdaterManagerCaller{contract: contract}, nil } -// NewUpdaterStorageTransactor creates a new write-only instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageTransactor(address common.Address, transactor bind.ContractTransactor) (*UpdaterStorageTransactor, error) { - contract, err := bindUpdaterStorage(address, nil, transactor, nil) +// NewUpdaterManagerTransactor creates a new write-only instance of UpdaterManager, bound to a specific deployed contract. +func NewUpdaterManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*UpdaterManagerTransactor, error) { + contract, err := bindUpdaterManager(address, nil, transactor, nil) if err != nil { return nil, err } - return &UpdaterStorageTransactor{contract: contract}, nil + return &UpdaterManagerTransactor{contract: contract}, nil } -// NewUpdaterStorageFilterer creates a new log filterer instance of UpdaterStorage, bound to a specific deployed contract. -func NewUpdaterStorageFilterer(address common.Address, filterer bind.ContractFilterer) (*UpdaterStorageFilterer, error) { - contract, err := bindUpdaterStorage(address, nil, nil, filterer) +// NewUpdaterManagerFilterer creates a new log filterer instance of UpdaterManager, bound to a specific deployed contract. +func NewUpdaterManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*UpdaterManagerFilterer, error) { + contract, err := bindUpdaterManager(address, nil, nil, filterer) if err != nil { return nil, err } - return &UpdaterStorageFilterer{contract: contract}, nil + return &UpdaterManagerFilterer{contract: contract}, nil } -// bindUpdaterStorage binds a generic wrapper to an already deployed contract. -func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := abi.JSON(strings.NewReader(UpdaterStorageABI)) +// bindUpdaterManager binds a generic wrapper to an already deployed contract. +func bindUpdaterManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(UpdaterManagerABI)) if err != nil { return nil, err } @@ -7848,77 +9345,46 @@ func bindUpdaterStorage(address common.Address, caller bind.ContractCaller, tran // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.UpdaterStorageCaller.contract.Call(opts, result, method, params...) +func (_UpdaterManager *UpdaterManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UpdaterManager.Contract.UpdaterManagerCaller.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transfer(opts) +func (_UpdaterManager *UpdaterManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UpdaterManager.Contract.UpdaterManagerTransactor.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.UpdaterStorageTransactor.contract.Transact(opts, method, params...) +func (_UpdaterManager *UpdaterManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UpdaterManager.Contract.UpdaterManagerTransactor.contract.Transact(opts, method, params...) } // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named // returns. -func (_UpdaterStorage *UpdaterStorageCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _UpdaterStorage.Contract.contract.Call(opts, result, method, params...) +func (_UpdaterManager *UpdaterManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _UpdaterManager.Contract.contract.Call(opts, result, method, params...) } // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transfer(opts) +func (_UpdaterManager *UpdaterManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UpdaterManager.Contract.contract.Transfer(opts) } // Transact invokes the (paid) contract method with params as input values. -func (_UpdaterStorage *UpdaterStorageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _UpdaterStorage.Contract.contract.Transact(opts, method, params...) -} - -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCaller) LocalDomain(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "localDomain") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - -} - -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) -} - -// LocalDomain is a free data retrieval call binding the contract method 0x8d3638f4. -// -// Solidity: function localDomain() view returns(uint32) -func (_UpdaterStorage *UpdaterStorageCallerSession) LocalDomain() (uint32, error) { - return _UpdaterStorage.Contract.LocalDomain(&_UpdaterStorage.CallOpts) +func (_UpdaterManager *UpdaterManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _UpdaterManager.Contract.contract.Transact(opts, method, params...) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// Home is a free data retrieval call binding the contract method 0x9fa92f9d. // -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Owner(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function home() view returns(address) +func (_UpdaterManager *UpdaterManagerCaller) Home(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "owner") + err := _UpdaterManager.contract.Call(opts, &out, "home") if err != nil { return *new(common.Address), err @@ -7930,26 +9396,26 @@ func (_UpdaterStorage *UpdaterStorageCaller) Owner(opts *bind.CallOpts) (common. } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// Home is a free data retrieval call binding the contract method 0x9fa92f9d. // -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) +// Solidity: function home() view returns(address) +func (_UpdaterManager *UpdaterManagerSession) Home() (common.Address, error) { + return _UpdaterManager.Contract.Home(&_UpdaterManager.CallOpts) } -// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// Home is a free data retrieval call binding the contract method 0x9fa92f9d. // -// Solidity: function owner() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Owner() (common.Address, error) { - return _UpdaterStorage.Contract.Owner(&_UpdaterStorage.CallOpts) +// Solidity: function home() view returns(address) +func (_UpdaterManager *UpdaterManagerCallerSession) Home() (common.Address, error) { + return _UpdaterManager.Contract.Home(&_UpdaterManager.CallOpts) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) SystemMessenger(opts *bind.CallOpts) (common.Address, error) { +// Solidity: function owner() view returns(address) +func (_UpdaterManager *UpdaterManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "systemMessenger") + err := _UpdaterManager.contract.Call(opts, &out, "owner") if err != nil { return *new(common.Address), err @@ -7961,26 +9427,26 @@ func (_UpdaterStorage *UpdaterStorageCaller) SystemMessenger(opts *bind.CallOpts } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) +// Solidity: function owner() view returns(address) +func (_UpdaterManager *UpdaterManagerSession) Owner() (common.Address, error) { + return _UpdaterManager.Contract.Owner(&_UpdaterManager.CallOpts) } -// SystemMessenger is a free data retrieval call binding the contract method 0xccbdf9c9. +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. // -// Solidity: function systemMessenger() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) SystemMessenger() (common.Address, error) { - return _UpdaterStorage.Contract.SystemMessenger(&_UpdaterStorage.CallOpts) +// Solidity: function owner() view returns(address) +func (_UpdaterManager *UpdaterManagerCallerSession) Owner() (common.Address, error) { + return _UpdaterManager.Contract.Owner(&_UpdaterManager.CallOpts) } // Updater is a free data retrieval call binding the contract method 0xdf034cd0. // // Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCaller) Updater(opts *bind.CallOpts) (common.Address, error) { +func (_UpdaterManager *UpdaterManagerCaller) Updater(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _UpdaterStorage.contract.Call(opts, &out, "updater") + err := _UpdaterManager.contract.Call(opts, &out, "updater") if err != nil { return *new(common.Address), err @@ -7995,83 +9461,125 @@ func (_UpdaterStorage *UpdaterStorageCaller) Updater(opts *bind.CallOpts) (commo // Updater is a free data retrieval call binding the contract method 0xdf034cd0. // // Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) +func (_UpdaterManager *UpdaterManagerSession) Updater() (common.Address, error) { + return _UpdaterManager.Contract.Updater(&_UpdaterManager.CallOpts) } // Updater is a free data retrieval call binding the contract method 0xdf034cd0. // // Solidity: function updater() view returns(address) -func (_UpdaterStorage *UpdaterStorageCallerSession) Updater() (common.Address, error) { - return _UpdaterStorage.Contract.Updater(&_UpdaterStorage.CallOpts) +func (_UpdaterManager *UpdaterManagerCallerSession) Updater() (common.Address, error) { + return _UpdaterManager.Contract.Updater(&_UpdaterManager.CallOpts) } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // // Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "renounceOwnership") +func (_UpdaterManager *UpdaterManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _UpdaterManager.contract.Transact(opts, "renounceOwnership") } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // // Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) +func (_UpdaterManager *UpdaterManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _UpdaterManager.Contract.RenounceOwnership(&_UpdaterManager.TransactOpts) } // RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. // // Solidity: function renounceOwnership() returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) RenounceOwnership() (*types.Transaction, error) { - return _UpdaterStorage.Contract.RenounceOwnership(&_UpdaterStorage.TransactOpts) +func (_UpdaterManager *UpdaterManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _UpdaterManager.Contract.RenounceOwnership(&_UpdaterManager.TransactOpts) } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// SetHome is a paid mutator transaction binding the contract method 0x6ef0f37f. // -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) SetSystemMessenger(opts *bind.TransactOpts, _systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "setSystemMessenger", _systemMessenger) +// Solidity: function setHome(address _home) returns() +func (_UpdaterManager *UpdaterManagerTransactor) SetHome(opts *bind.TransactOpts, _home common.Address) (*types.Transaction, error) { + return _UpdaterManager.contract.Transact(opts, "setHome", _home) } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// SetHome is a paid mutator transaction binding the contract method 0x6ef0f37f. // -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// Solidity: function setHome(address _home) returns() +func (_UpdaterManager *UpdaterManagerSession) SetHome(_home common.Address) (*types.Transaction, error) { + return _UpdaterManager.Contract.SetHome(&_UpdaterManager.TransactOpts, _home) } -// SetSystemMessenger is a paid mutator transaction binding the contract method 0xb7bc563e. +// SetHome is a paid mutator transaction binding the contract method 0x6ef0f37f. // -// Solidity: function setSystemMessenger(address _systemMessenger) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) SetSystemMessenger(_systemMessenger common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.SetSystemMessenger(&_UpdaterStorage.TransactOpts, _systemMessenger) +// Solidity: function setHome(address _home) returns() +func (_UpdaterManager *UpdaterManagerTransactorSession) SetHome(_home common.Address) (*types.Transaction, error) { + return _UpdaterManager.Contract.SetHome(&_UpdaterManager.TransactOpts, _home) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updaterAddress) returns() +func (_UpdaterManager *UpdaterManagerTransactor) SetUpdater(opts *bind.TransactOpts, _updaterAddress common.Address) (*types.Transaction, error) { + return _UpdaterManager.contract.Transact(opts, "setUpdater", _updaterAddress) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updaterAddress) returns() +func (_UpdaterManager *UpdaterManagerSession) SetUpdater(_updaterAddress common.Address) (*types.Transaction, error) { + return _UpdaterManager.Contract.SetUpdater(&_UpdaterManager.TransactOpts, _updaterAddress) +} + +// SetUpdater is a paid mutator transaction binding the contract method 0x9d54f419. +// +// Solidity: function setUpdater(address _updaterAddress) returns() +func (_UpdaterManager *UpdaterManagerTransactorSession) SetUpdater(_updaterAddress common.Address) (*types.Transaction, error) { + return _UpdaterManager.Contract.SetUpdater(&_UpdaterManager.TransactOpts, _updaterAddress) +} + +// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. +// +// Solidity: function slashUpdater(address _reporter) returns() +func (_UpdaterManager *UpdaterManagerTransactor) SlashUpdater(opts *bind.TransactOpts, _reporter common.Address) (*types.Transaction, error) { + return _UpdaterManager.contract.Transact(opts, "slashUpdater", _reporter) +} + +// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. +// +// Solidity: function slashUpdater(address _reporter) returns() +func (_UpdaterManager *UpdaterManagerSession) SlashUpdater(_reporter common.Address) (*types.Transaction, error) { + return _UpdaterManager.Contract.SlashUpdater(&_UpdaterManager.TransactOpts, _reporter) +} + +// SlashUpdater is a paid mutator transaction binding the contract method 0x5b3c2cbf. +// +// Solidity: function slashUpdater(address _reporter) returns() +func (_UpdaterManager *UpdaterManagerTransactorSession) SlashUpdater(_reporter common.Address) (*types.Transaction, error) { + return _UpdaterManager.Contract.SlashUpdater(&_UpdaterManager.TransactOpts, _reporter) } // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.contract.Transact(opts, "transferOwnership", newOwner) +func (_UpdaterManager *UpdaterManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _UpdaterManager.contract.Transact(opts, "transferOwnership", newOwner) } // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +func (_UpdaterManager *UpdaterManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _UpdaterManager.Contract.TransferOwnership(&_UpdaterManager.TransactOpts, newOwner) } // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() -func (_UpdaterStorage *UpdaterStorageTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { - return _UpdaterStorage.Contract.TransferOwnership(&_UpdaterStorage.TransactOpts, newOwner) +func (_UpdaterManager *UpdaterManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _UpdaterManager.Contract.TransferOwnership(&_UpdaterManager.TransactOpts, newOwner) } -// UpdaterStorageInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the UpdaterStorage contract. -type UpdaterStorageInitializedIterator struct { - Event *UpdaterStorageInitialized // Event containing the contract specifics and raw log +// UpdaterManagerFakeSlashedIterator is returned from FilterFakeSlashed and is used to iterate over the raw logs and unpacked data for FakeSlashed events raised by the UpdaterManager contract. +type UpdaterManagerFakeSlashedIterator struct { + Event *UpdaterManagerFakeSlashed // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -8085,7 +9593,7 @@ type UpdaterStorageInitializedIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageInitializedIterator) Next() bool { +func (it *UpdaterManagerFakeSlashedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -8094,7 +9602,7 @@ func (it *UpdaterStorageInitializedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) + it.Event = new(UpdaterManagerFakeSlashed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -8109,7 +9617,7 @@ func (it *UpdaterStorageInitializedIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(UpdaterStorageInitialized) + it.Event = new(UpdaterManagerFakeSlashed) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -8125,41 +9633,41 @@ func (it *UpdaterStorageInitializedIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageInitializedIterator) Error() error { +func (it *UpdaterManagerFakeSlashedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *UpdaterStorageInitializedIterator) Close() error { +func (it *UpdaterManagerFakeSlashedIterator) Close() error { it.sub.Unsubscribe() return nil } -// UpdaterStorageInitialized represents a Initialized event raised by the UpdaterStorage contract. -type UpdaterStorageInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos +// UpdaterManagerFakeSlashed represents a FakeSlashed event raised by the UpdaterManager contract. +type UpdaterManagerFakeSlashed struct { + Reporter common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// FilterFakeSlashed is a free log retrieval operation binding the contract event 0x4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f. // -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterInitialized(opts *bind.FilterOpts) (*UpdaterStorageInitializedIterator, error) { +// Solidity: event FakeSlashed(address reporter) +func (_UpdaterManager *UpdaterManagerFilterer) FilterFakeSlashed(opts *bind.FilterOpts) (*UpdaterManagerFakeSlashedIterator, error) { - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Initialized") + logs, sub, err := _UpdaterManager.contract.FilterLogs(opts, "FakeSlashed") if err != nil { return nil, err } - return &UpdaterStorageInitializedIterator{contract: _UpdaterStorage.contract, event: "Initialized", logs: logs, sub: sub}, nil + return &UpdaterManagerFakeSlashedIterator{contract: _UpdaterManager.contract, event: "FakeSlashed", logs: logs, sub: sub}, nil } -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// WatchFakeSlashed is a free log subscription operation binding the contract event 0x4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f. // -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *UpdaterStorageInitialized) (event.Subscription, error) { +// Solidity: event FakeSlashed(address reporter) +func (_UpdaterManager *UpdaterManagerFilterer) WatchFakeSlashed(opts *bind.WatchOpts, sink chan<- *UpdaterManagerFakeSlashed) (event.Subscription, error) { - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Initialized") + logs, sub, err := _UpdaterManager.contract.WatchLogs(opts, "FakeSlashed") if err != nil { return nil, err } @@ -8169,8 +9677,8 @@ func (_UpdaterStorage *UpdaterStorageFilterer) WatchInitialized(opts *bind.Watch select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { + event := new(UpdaterManagerFakeSlashed) + if err := _UpdaterManager.contract.UnpackLog(event, "FakeSlashed", log); err != nil { return err } event.Raw = log @@ -8191,21 +9699,21 @@ func (_UpdaterStorage *UpdaterStorageFilterer) WatchInitialized(opts *bind.Watch }), nil } -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// ParseFakeSlashed is a log parse operation binding the contract event 0x4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f. // -// Solidity: event Initialized(uint8 version) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseInitialized(log types.Log) (*UpdaterStorageInitialized, error) { - event := new(UpdaterStorageInitialized) - if err := _UpdaterStorage.contract.UnpackLog(event, "Initialized", log); err != nil { +// Solidity: event FakeSlashed(address reporter) +func (_UpdaterManager *UpdaterManagerFilterer) ParseFakeSlashed(log types.Log) (*UpdaterManagerFakeSlashed, error) { + event := new(UpdaterManagerFakeSlashed) + if err := _UpdaterManager.contract.UnpackLog(event, "FakeSlashed", log); err != nil { return nil, err } event.Raw = log return event, nil } -// UpdaterStorageNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdaterIterator struct { - Event *UpdaterStorageNewUpdater // Event containing the contract specifics and raw log +// UpdaterManagerNewHomeIterator is returned from FilterNewHome and is used to iterate over the raw logs and unpacked data for NewHome events raised by the UpdaterManager contract. +type UpdaterManagerNewHomeIterator struct { + Event *UpdaterManagerNewHome // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -8219,7 +9727,7 @@ type UpdaterStorageNewUpdaterIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageNewUpdaterIterator) Next() bool { +func (it *UpdaterManagerNewHomeIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -8228,7 +9736,7 @@ func (it *UpdaterStorageNewUpdaterIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) + it.Event = new(UpdaterManagerNewHome) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -8243,7 +9751,7 @@ func (it *UpdaterStorageNewUpdaterIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(UpdaterStorageNewUpdater) + it.Event = new(UpdaterManagerNewHome) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -8259,42 +9767,41 @@ func (it *UpdaterStorageNewUpdaterIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageNewUpdaterIterator) Error() error { +func (it *UpdaterManagerNewHomeIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *UpdaterStorageNewUpdaterIterator) Close() error { +func (it *UpdaterManagerNewHomeIterator) Close() error { it.sub.Unsubscribe() return nil } -// UpdaterStorageNewUpdater represents a NewUpdater event raised by the UpdaterStorage contract. -type UpdaterStorageNewUpdater struct { - OldUpdater common.Address - NewUpdater common.Address - Raw types.Log // Blockchain specific contextual infos +// UpdaterManagerNewHome represents a NewHome event raised by the UpdaterManager contract. +type UpdaterManagerNewHome struct { + Home common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterNewUpdater is a free log retrieval operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// FilterNewHome is a free log retrieval operation binding the contract event 0xa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de21. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*UpdaterStorageNewUpdaterIterator, error) { +// Solidity: event NewHome(address home) +func (_UpdaterManager *UpdaterManagerFilterer) FilterNewHome(opts *bind.FilterOpts) (*UpdaterManagerNewHomeIterator, error) { - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "NewUpdater") + logs, sub, err := _UpdaterManager.contract.FilterLogs(opts, "NewHome") if err != nil { return nil, err } - return &UpdaterStorageNewUpdaterIterator{contract: _UpdaterStorage.contract, event: "NewUpdater", logs: logs, sub: sub}, nil + return &UpdaterManagerNewHomeIterator{contract: _UpdaterManager.contract, event: "NewHome", logs: logs, sub: sub}, nil } -// WatchNewUpdater is a free log subscription operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// WatchNewHome is a free log subscription operation binding the contract event 0xa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de21. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *UpdaterStorageNewUpdater) (event.Subscription, error) { +// Solidity: event NewHome(address home) +func (_UpdaterManager *UpdaterManagerFilterer) WatchNewHome(opts *bind.WatchOpts, sink chan<- *UpdaterManagerNewHome) (event.Subscription, error) { - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "NewUpdater") + logs, sub, err := _UpdaterManager.contract.WatchLogs(opts, "NewHome") if err != nil { return nil, err } @@ -8304,8 +9811,8 @@ func (_UpdaterStorage *UpdaterStorageFilterer) WatchNewUpdater(opts *bind.WatchO select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { + event := new(UpdaterManagerNewHome) + if err := _UpdaterManager.contract.UnpackLog(event, "NewHome", log); err != nil { return err } event.Raw = log @@ -8326,21 +9833,21 @@ func (_UpdaterStorage *UpdaterStorageFilterer) WatchNewUpdater(opts *bind.WatchO }), nil } -// ParseNewUpdater is a log parse operation binding the contract event 0x0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a. +// ParseNewHome is a log parse operation binding the contract event 0xa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de21. // -// Solidity: event NewUpdater(address oldUpdater, address newUpdater) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseNewUpdater(log types.Log) (*UpdaterStorageNewUpdater, error) { - event := new(UpdaterStorageNewUpdater) - if err := _UpdaterStorage.contract.UnpackLog(event, "NewUpdater", log); err != nil { +// Solidity: event NewHome(address home) +func (_UpdaterManager *UpdaterManagerFilterer) ParseNewHome(log types.Log) (*UpdaterManagerNewHome, error) { + event := new(UpdaterManagerNewHome) + if err := _UpdaterManager.contract.UnpackLog(event, "NewHome", log); err != nil { return nil, err } event.Raw = log return event, nil } -// UpdaterStorageOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferredIterator struct { - Event *UpdaterStorageOwnershipTransferred // Event containing the contract specifics and raw log +// UpdaterManagerNewUpdaterIterator is returned from FilterNewUpdater and is used to iterate over the raw logs and unpacked data for NewUpdater events raised by the UpdaterManager contract. +type UpdaterManagerNewUpdaterIterator struct { + Event *UpdaterManagerNewUpdater // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -8354,7 +9861,7 @@ type UpdaterStorageOwnershipTransferredIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageOwnershipTransferredIterator) Next() bool { +func (it *UpdaterManagerNewUpdaterIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -8363,7 +9870,7 @@ func (it *UpdaterStorageOwnershipTransferredIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) + it.Event = new(UpdaterManagerNewUpdater) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -8378,7 +9885,7 @@ func (it *UpdaterStorageOwnershipTransferredIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(UpdaterStorageOwnershipTransferred) + it.Event = new(UpdaterManagerNewUpdater) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -8394,60 +9901,41 @@ func (it *UpdaterStorageOwnershipTransferredIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageOwnershipTransferredIterator) Error() error { +func (it *UpdaterManagerNewUpdaterIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *UpdaterStorageOwnershipTransferredIterator) Close() error { +func (it *UpdaterManagerNewUpdaterIterator) Close() error { it.sub.Unsubscribe() return nil } -// UpdaterStorageOwnershipTransferred represents a OwnershipTransferred event raised by the UpdaterStorage contract. -type UpdaterStorageOwnershipTransferred struct { - PreviousOwner common.Address - NewOwner common.Address - Raw types.Log // Blockchain specific contextual infos +// UpdaterManagerNewUpdater represents a NewUpdater event raised by the UpdaterManager contract. +type UpdaterManagerNewUpdater struct { + Updater common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// FilterNewUpdater is a free log retrieval operation binding the contract event 0x9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c32. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UpdaterStorageOwnershipTransferredIterator, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Solidity: event NewUpdater(address updater) +func (_UpdaterManager *UpdaterManagerFilterer) FilterNewUpdater(opts *bind.FilterOpts) (*UpdaterManagerNewUpdaterIterator, error) { - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _UpdaterManager.contract.FilterLogs(opts, "NewUpdater") if err != nil { return nil, err } - return &UpdaterStorageOwnershipTransferredIterator{contract: _UpdaterStorage.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil + return &UpdaterManagerNewUpdaterIterator{contract: _UpdaterManager.contract, event: "NewUpdater", logs: logs, sub: sub}, nil } -// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// WatchNewUpdater is a free log subscription operation binding the contract event 0x9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c32. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UpdaterStorageOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - - var previousOwnerRule []interface{} - for _, previousOwnerItem := range previousOwner { - previousOwnerRule = append(previousOwnerRule, previousOwnerItem) - } - var newOwnerRule []interface{} - for _, newOwnerItem := range newOwner { - newOwnerRule = append(newOwnerRule, newOwnerItem) - } +// Solidity: event NewUpdater(address updater) +func (_UpdaterManager *UpdaterManagerFilterer) WatchNewUpdater(opts *bind.WatchOpts, sink chan<- *UpdaterManagerNewUpdater) (event.Subscription, error) { - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + logs, sub, err := _UpdaterManager.contract.WatchLogs(opts, "NewUpdater") if err != nil { return nil, err } @@ -8457,8 +9945,8 @@ func (_UpdaterStorage *UpdaterStorageFilterer) WatchOwnershipTransferred(opts *b select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + event := new(UpdaterManagerNewUpdater) + if err := _UpdaterManager.contract.UnpackLog(event, "NewUpdater", log); err != nil { return err } event.Raw = log @@ -8479,21 +9967,21 @@ func (_UpdaterStorage *UpdaterStorageFilterer) WatchOwnershipTransferred(opts *b }), nil } -// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// ParseNewUpdater is a log parse operation binding the contract event 0x9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c32. // -// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseOwnershipTransferred(log types.Log) (*UpdaterStorageOwnershipTransferred, error) { - event := new(UpdaterStorageOwnershipTransferred) - if err := _UpdaterStorage.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { +// Solidity: event NewUpdater(address updater) +func (_UpdaterManager *UpdaterManagerFilterer) ParseNewUpdater(log types.Log) (*UpdaterManagerNewUpdater, error) { + event := new(UpdaterManagerNewUpdater) + if err := _UpdaterManager.contract.UnpackLog(event, "NewUpdater", log); err != nil { return nil, err } event.Raw = log return event, nil } -// UpdaterStorageUpdateIterator is returned from FilterUpdate and is used to iterate over the raw logs and unpacked data for Update events raised by the UpdaterStorage contract. -type UpdaterStorageUpdateIterator struct { - Event *UpdaterStorageUpdate // Event containing the contract specifics and raw log +// UpdaterManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the UpdaterManager contract. +type UpdaterManagerOwnershipTransferredIterator struct { + Event *UpdaterManagerOwnershipTransferred // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -8507,7 +9995,7 @@ type UpdaterStorageUpdateIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *UpdaterStorageUpdateIterator) Next() bool { +func (it *UpdaterManagerOwnershipTransferredIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -8516,7 +10004,7 @@ func (it *UpdaterStorageUpdateIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) + it.Event = new(UpdaterManagerOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -8531,7 +10019,7 @@ func (it *UpdaterStorageUpdateIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(UpdaterStorageUpdate) + it.Event = new(UpdaterManagerOwnershipTransferred) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -8547,70 +10035,60 @@ func (it *UpdaterStorageUpdateIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *UpdaterStorageUpdateIterator) Error() error { +func (it *UpdaterManagerOwnershipTransferredIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *UpdaterStorageUpdateIterator) Close() error { +func (it *UpdaterManagerOwnershipTransferredIterator) Close() error { it.sub.Unsubscribe() return nil } -// UpdaterStorageUpdate represents a Update event raised by the UpdaterStorage contract. -type UpdaterStorageUpdate struct { - HomeDomain uint32 - Nonce uint32 - Root [32]byte - Signature []byte - Raw types.Log // Blockchain specific contextual infos +// UpdaterManagerOwnershipTransferred represents a OwnershipTransferred event raised by the UpdaterManager contract. +type UpdaterManagerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterUpdate is a free log retrieval operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) FilterUpdate(opts *bind.FilterOpts, homeDomain []uint32, nonce []uint32, root [][32]byte) (*UpdaterStorageUpdateIterator, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_UpdaterManager *UpdaterManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*UpdaterManagerOwnershipTransferredIterator, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _UpdaterStorage.contract.FilterLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _UpdaterManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } - return &UpdaterStorageUpdateIterator{contract: _UpdaterStorage.contract, event: "Update", logs: logs, sub: sub}, nil + return &UpdaterManagerOwnershipTransferredIterator{contract: _UpdaterManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil } -// WatchUpdate is a free log subscription operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) WatchUpdate(opts *bind.WatchOpts, sink chan<- *UpdaterStorageUpdate, homeDomain []uint32, nonce []uint32, root [][32]byte) (event.Subscription, error) { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_UpdaterManager *UpdaterManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *UpdaterManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { - var homeDomainRule []interface{} - for _, homeDomainItem := range homeDomain { - homeDomainRule = append(homeDomainRule, homeDomainItem) - } - var nonceRule []interface{} - for _, nonceItem := range nonce { - nonceRule = append(nonceRule, nonceItem) + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) } - var rootRule []interface{} - for _, rootItem := range root { - rootRule = append(rootRule, rootItem) + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) } - logs, sub, err := _UpdaterStorage.contract.WatchLogs(opts, "Update", homeDomainRule, nonceRule, rootRule) + logs, sub, err := _UpdaterManager.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) if err != nil { return nil, err } @@ -8620,8 +10098,8 @@ func (_UpdaterStorage *UpdaterStorageFilterer) WatchUpdate(opts *bind.WatchOpts, select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { + event := new(UpdaterManagerOwnershipTransferred) + if err := _UpdaterManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return err } event.Raw = log @@ -8642,12 +10120,12 @@ func (_UpdaterStorage *UpdaterStorageFilterer) WatchUpdate(opts *bind.WatchOpts, }), nil } -// ParseUpdate is a log parse operation binding the contract event 0x3f459c2c4e333807b9c629230cbac6a23dbfd53c030ef9bc6886abb97ada9171. +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. // -// Solidity: event Update(uint32 indexed homeDomain, uint32 indexed nonce, bytes32 indexed root, bytes signature) -func (_UpdaterStorage *UpdaterStorageFilterer) ParseUpdate(log types.Log) (*UpdaterStorageUpdate, error) { - event := new(UpdaterStorageUpdate) - if err := _UpdaterStorage.contract.UnpackLog(event, "Update", log); err != nil { +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_UpdaterManager *UpdaterManagerFilterer) ParseOwnershipTransferred(log types.Log) (*UpdaterManagerOwnershipTransferred, error) { + event := new(UpdaterManagerOwnershipTransferred) + if err := _UpdaterManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { return nil, err } event.Raw = log @@ -8660,7 +10138,7 @@ var Version0MetaData = &bind.MetaData{ Sigs: map[string]string{ "ffa1ad74": "VERSION()", }, - Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220147957fda2ff464ad00468048258af6268e10639ff3cebac8e6d8f510d6c982d64736f6c634300080d0033", + Bin: "0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208e7a175bf2a5d2eca4f04a20dce3075bc55167057de74d26eba65775fcc685b464736f6c634300080d0033", } // Version0ABI is the input ABI used to generate the binding from. diff --git a/core/contracts/updatermanager/updatemanager.contractinfo.json b/core/contracts/updatermanager/updatemanager.contractinfo.json index 8efb72142a..625cbc03f5 100644 --- a/core/contracts/updatermanager/updatemanager.contractinfo.json +++ b/core/contracts/updatermanager/updatemanager.contractinfo.json @@ -1 +1 @@ -{"solidity/UpdaterManager.sol:Address":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f2b2b5dedff2c43ed96b31a6c55c27c393332adc0f7c50d60ace08bba94afb0364736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220f2b2b5dedff2c43ed96b31a6c55c27c393332adc0f7c50d60ace08bba94afb0364736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"96866:8061:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;96866:8061:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"96866:8061:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Address\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220efddb409a34a8de640a795f00749b7b1f9a7882c1f54721830599fbabcc1460464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220efddb409a34a8de640a795f00749b7b1f9a7882c1f54721830599fbabcc1460464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"53678:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;53678:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"53678:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202b98152b11399d8db72cf434b62ace04bacd73ccb14ac7e7f684d00b38e6a15e64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202b98152b11399d8db72cf434b62ace04bacd73ccb14ac7e7f684d00b38e6a15e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"73178:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;73178:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"73178:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202b29159cd74b901c4dfcb0d00f8df2caaf365677497165a08f18e9108bb0467764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212202b29159cd74b901c4dfcb0d00f8df2caaf365677497165a08f18e9108bb0467764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"76396:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;76396:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"76396:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:AuthManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"AuthManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Context":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Context\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207aa88a93de95559c8a6d7dd8d1fbfc1e6c5dfe1cb45b9417d5276f32f5f0829a64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207aa88a93de95559c8a6d7dd8d1fbfc1e6c5dfe1cb45b9417d5276f32f5f0829a64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"44612:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;44612:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"44612:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220927355e562dbb5a47568edd04452b2df5ed7678deae00c86b947df6ee4c9359764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220927355e562dbb5a47568edd04452b2df5ed7678deae00c86b947df6ee4c9359764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"39328:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;39328:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"39328:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Home":{"code":"0x60a06040523480156200001157600080fd5b50604051620036d9380380620036d9833981016040819052620000349162000043565b63ffffffff1660805262000072565b6000602082840312156200005657600080fd5b815163ffffffff811681146200006b57600080fd5b9392505050565b60805161363d6200009c6000396000818161025e01528181610d9c01526117a3015261363d6000f3fe6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220b3b337c9ceb3f8e191b14a91c40b33fb4e8d91c3e456e5e6bcdea6b2f771e7e464736f6c634300080d0033","runtime-code":"0x6080604052600436106101755760003560e01c8063affed0e0116100cb578063df034cd01161007f578063f7560e4011610059578063f7560e4014610488578063fd54b2281461049b578063ffa1ad74146104b257600080fd5b8063df034cd014610426578063ebf0c71714610453578063f2fde38b1461046857600080fd5b8063c19d93fb116100b0578063c19d93fb14610395578063c4d66de8146103d9578063ccbdf9c9146103f957600080fd5b8063affed0e014610357578063b7bc563e1461037557600080fd5b80637ea97f401161012d5780639776120e116101075780639776120e146102e15780639d54f419146103015780639df6c8e11461032157600080fd5b80637ea97f401461022c5780638d3638f41461024c5780638da5cb5b1461029557600080fd5b806336e104de1161015e57806336e104de146101ce578063522ae002146101ff578063715018a61461021557600080fd5b806306661abd1461017a5780630afe7f901461019e575b600080fd5b34801561018657600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101aa57600080fd5b506101be6101b9366004612ef6565b6104d9565b6040519015158152602001610195565b3480156101da57600080fd5b506101e361062f565b6040805163ffffffff9093168352602083019190915201610195565b34801561020b57600080fd5b5061018b61080081565b34801561022157600080fd5b5061022a610676565b005b34801561023857600080fd5b5061018b610247366004612f2b565b6106df565b34801561025857600080fd5b506102807f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff9091168152602001610195565b3480156102a157600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610195565b3480156102ed57600080fd5b5061022a6102fc366004612f66565b610700565b34801561030d57600080fd5b5061022a61031c366004612f66565b610773565b34801561032d57600080fd5b5061011b546102bc90640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561036357600080fd5b5061011b546102809063ffffffff1681565b34801561038157600080fd5b5061022a610390366004612f66565b610833565b3480156103a157600080fd5b5061011b546103cc907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101959190612fb2565b3480156103e557600080fd5b5061022a6103f4366004612f66565b6108e1565b34801561040557600080fd5b5060b8546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561043257600080fd5b5060b7546102bc9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561045f57600080fd5b5061018b610aa3565b34801561047457600080fd5b5061022a610483366004612f66565b610ab4565b61022a610496366004613007565b610bad565b3480156104a757600080fd5b5060205461018b9081565b3480156104be57600080fd5b506104c7600081565b60405160ff9091168152602001610195565b6000600261011b547801000000000000000000000000000000000000000000000000900460ff16600281111561051157610511612f83565b036105635760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061056f84610ea7565b9150915060006105848262ffffff1916610fb7565b9050600061059762ffffff198416610fd1565b60215490915063ffffffff831610156105e05760218263ffffffff16815481106105c3576105c3613096565b906000526020600020015481036105e05750600095945050505050565b6105e8610fe6565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b848760405161061992919061313f565b60405180910390a160019450505050505b919050565b602154600090819080156106715761064860018261319d565b925060218363ffffffff168154811061066357610663613096565b906000526020600020015491505b509091565b60855473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b565b602181815481106106ef57600080fd5b600091825260209091200154905081565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b61077081611101565b50565b61011b54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146107e35760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e616765720000000000000000000000000000000000604482015260640161055a565b6107ec816111e9565b5061011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60855473ffffffffffffffffffffffffffffffffffffffff16331461089a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b60b880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006108ed6001611268565b9050801561092257605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b61092b82611101565b6109c561011b60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906131b4565b6113bc565b61011b80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610a9f57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b5050565b6000610aaf600061144a565b905090565b60855473ffffffffffffffffffffffffffffffffffffffff163314610b1b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055a565b73ffffffffffffffffffffffffffffffffffffffff8116610ba45760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161055a565b6107708161145d565b600261011b547801000000000000000000000000000000000000000000000000900460ff166002811115610be357610be3612f83565b03610c305760405162461bcd60e51b815260206004820152600c60248201527f6661696c65642073746174650000000000000000000000000000000000000000604482015260640161055a565b61080081511115610c835760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e670000000000000000000000000000000000000000604482015260640161055a565b34610c9b610c90846114d4565b62ffffff19166114e1565b6bffffffffffffffffffffffff1614610cf65760405162461bcd60e51b815260206004820152600560248201527f2174697073000000000000000000000000000000000000000000000000000000604482015260640161055a565b61011b54610d0b9063ffffffff1660016131d1565b61011b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610d4c85611543565b61011b54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610e168286866115a2565b80516020820120909150610e298161161d565b61011b5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610e5860205490565b610e62919061319d565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610e949291906131f9565b60405180910390a4505050505050505050565b600080610eb4838261164d565b905060286bffffffffffffffffffffffff601883901c1611610f185760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e0000000000000000000000000000604482015260640161055a565b610f4c610f2a62ffffff198316611671565b610f47610f3c62ffffff198516611686565b62ffffff19166116b9565b61170c565b9150610f66610f6062ffffff19831661178b565b8361179f565b610fb25760405162461bcd60e51b815260206004820152601860248201527f5369676e6572206973206e6f7420616e20757064617465720000000000000000604482015260640161055a565b915091565b6000610fcb62ffffff198316600480611840565b92915050565b6000610fcb62ffffff19831660086020611870565b61011b805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156110a057600080fd5b505af11580156110b4573d6000803e3d6000fd5b505060b75460405133935073ffffffffffffffffffffffffffffffffffffffff90911691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a3565b73ffffffffffffffffffffffffffffffffffffffff81163b6111655760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e616765720000000000000000604482015260640161055a565b61011b80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b60b7805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f0f20622a7af9e952a6fec654a196f29e04477b5d335772c26902bec35cc9f22a9101610a96565b605254600090610100900460ff1615611307578160ff16600114801561128d5750303b155b6112ff5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b506000919050565b60525460ff8084169116106113845760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161055a565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166114395760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b611441611a2e565b610770816111e9565b6000610fcb82611458611ab3565b611f74565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610fcb82600261164d565b6000816114f760025b62ffffff19831690612037565b5061150183612138565b61150a84612166565b61151385612187565b61151c866121a8565b611526919061321e565b611530919061321e565b61153a919061321e565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611573573392915050565b61157b6121c9565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906115b660046002613245565b60ff166115c3919061326e565b905060008451826115d4919061326e565b905060016115e460046002613245565b60ff168383898989604051602001611602979695949392919061328b565b604051602081830303815290604052925050505b9392505050565b611628600082612230565b6021611634600061144a565b8154600181018355600092835260209092209091015550565b81516000906020840161166864ffffffffff85168284612353565b95945050505050565b6000610fcb62ffffff1983168260288161239a565b6000610fcb60286116a981601886901c6bffffffffffffffffffffffff1661319d565b62ffffff1985169190600061239a565b60606000806116d68460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506116fb848360200161241e565b508181016020016040529052919050565b60008061171e62ffffff1985166125b9565b9050611777816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506117838184612616565b949350505050565b6000610fcb62ffffff198316826004611840565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff161461181c5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e0000000000000000000000000000000000000000604482015260640161055a565b5060b75473ffffffffffffffffffffffffffffffffffffffff908116911614919050565b600061184d826020613329565b611858906008613245565b60ff16611866858585611870565b901c949350505050565b60008160ff1660000361188557506000611616565b61189d8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118b860ff84168561334c565b1115611930576119176118d98560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166118ff8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff1661263a565b60405162461bcd60e51b815260040161055a9190613364565b60208260ff1611156119aa5760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e203332206279746573000000000000606482015260840161055a565b6008820260006119c88660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b605254610100900460ff16611aab5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd6126a8565b611abb612dfd565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561202f57600182821c811690819003611fdb57858260208110611fa857611fa8613096565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350612026565b83858360208110611fee57611fee613096565b602002015160405160200161200d929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101611f7e565b505092915050565b6000612043838361272e565b6121315760006120626120568560d81c90565b64ffffffffff16612751565b91505060006120778464ffffffffff16612751565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b815260040161055a9190613364565b5090919050565b60008161214560026114ea565b5061215962ffffff1984166026600c611840565b63ffffffff169392505050565b60008161217360026114ea565b5061215962ffffff198416601a600c611840565b60008161219460026114ea565b5061215962ffffff198416600e600c611840565b6000816121b560026114ea565b5061215962ffffff1984166002600c611840565b60b85473ffffffffffffffffffffffffffffffffffffffff1633146106dd5760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e67657200000000000000000000000000000000604482015260640161055a565b6020808301549060019061224590600261348f565b61224f919061319d565b811061229d5760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c00000000000000000000000000000000604482015260640161055a565b6001016020830181905560005b602081101561234557816001166001036122d957828482602081106122d1576122d1613096565b015550505050565b8381602081106122eb576122eb613096565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c91016122aa565b5061234e61349b565b505050565b600080612360838561334c565b9050604051811115612370575060005b806000036123855762ffffff19915050611616565b5050606092831b9190911790911b1760181b90565b6000806123b58660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff1690506123ce8661283b565b846123d9878461334c565b6123e3919061334c565b11156123f65762ffffff19915050611783565b612400858261334c565b90506124148364ffffffffff168286612353565b9695505050505050565b600062ffffff198084160361249b5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f6572206465726566000000000000000000000000000000000000000000000000606482015260840161055a565b6124a483612883565b6125165760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e746572206465726566000000000000000000000000000000000000000000606482015260840161055a565b60006125308460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600061255a8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050600060405190508481111561257f5760206060fd5b8285848460045afa506124146125958760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806125d48360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006125fe8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b600080600061262585856128c0565b915091506126328161292e565b509392505050565b6060600061264786612751565b915050600061265586612751565b915050600061266386612751565b915050600061267186612751565b9150508383838360405160200161268b94939291906134ca565b604051602081830303815290604052945050505050949350505050565b605254610100900460ff166127255760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161055a565b6106dd3361145d565b60008164ffffffffff166127428460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156127c4576000612770826008613245565b60ff1685901c905061278181612b1a565b61ffff16841793508160ff1660101461279c57601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612757565b50600f5b60ff8160ff1610156128355760006127e1826008613245565b60ff1685901c90506127f281612b1a565b61ffff16831792508160ff1660001461280d57601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016127c8565b50915091565b60006128558260181c6bffffffffffffffffffffffff1690565b61286d8360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b600061288f8260d81c90565b64ffffffffff1664ffffffffff036128a957506000919050565b60006128b48361283b565b60405110199392505050565b60008082516041036128f65760208301516040840151606085015160001a6128ea87828585612b4c565b94509450505050612927565b825160400361291f5760208301516040840151612914868383612c64565b935093505050612927565b506000905060025b9250929050565b600081600481111561294257612942612f83565b0361294a5750565b600181600481111561295e5761295e612f83565b036129ab5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161055a565b60028160048111156129bf576129bf612f83565b03612a0c5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161055a565b6003816004811115612a2057612a20612f83565b03612a935760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6004816004811115612aa757612aa7612f83565b036107705760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161055a565b6000612b2c60048360ff16901c612cb6565b60ff1661ffff919091161760081b612b4382612cb6565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612b835750600090506003612c5b565b8460ff16601b14158015612b9b57508460ff16601c14155b15612bac5750600090506004612c5b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612c00573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612c5457600060019250925050612c5b565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612c9a60ff86901c601b61334c565b9050612ca887828885612b4c565b935093505050935093915050565b600060f08083179060ff82169003612cd15750603092915050565b8060ff1660f103612ce55750603192915050565b8060ff1660f203612cf95750603292915050565b8060ff1660f303612d0d5750603392915050565b8060ff1660f403612d215750603492915050565b8060ff1660f503612d355750603592915050565b8060ff1660f603612d495750603692915050565b8060ff1660f703612d5d5750603792915050565b8060ff1660f803612d715750603892915050565b8060ff1660f903612d855750603992915050565b8060ff1660fa03612d995750606192915050565b8060ff1660fb03612dad5750606292915050565b8060ff1660fc03612dc15750606392915050565b8060ff1660fd03612dd55750606492915050565b8060ff1660fe03612de95750606592915050565b8060ff1660ff0361153d5750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612e5c57600080fd5b813567ffffffffffffffff80821115612e7757612e77612e1c565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612ebd57612ebd612e1c565b81604052838152866020858801011115612ed657600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215612f0857600080fd5b813567ffffffffffffffff811115612f1f57600080fd5b61178384828501612e4b565b600060208284031215612f3d57600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461077057600080fd5b600060208284031215612f7857600080fd5b813561161681612f44565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612fed577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff8116811461062a57600080fd5b600080600080600060a0868803121561301f57600080fd5b61302886612ff3565b94506020860135935061303d60408701612ff3565b9250606086013567ffffffffffffffff8082111561305a57600080fd5b61306689838a01612e4b565b9350608088013591508082111561307c57600080fd5b5061308988828901612e4b565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156130e05781810151838201526020016130c8565b838111156130ef576000848401525b50505050565b6000815180845261310d8160208601602086016130c5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061178360408301846130f5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156131af576131af61316e565b500390565b6000602082840312156131c657600080fd5b815161161681612f44565b600063ffffffff8083168185168083038211156131f0576131f061316e565b01949350505050565b60408152600061320c60408301856130f5565b828103602084015261166881856130f5565b60006bffffffffffffffffffffffff8083168185168083038211156131f0576131f061316e565b600060ff821660ff84168160ff04811182151516156132665761326661316e565b029392505050565b600061ffff8083168185168083038211156131f0576131f061316e565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516132eb8160088501602089016130c5565b8451908301906133028160088401602089016130c5565b84519101906133188160088401602088016130c5565b016008019998505050505050505050565b600060ff821660ff8416808210156133435761334361316e565b90039392505050565b6000821982111561335f5761335f61316e565b500190565b60208152600061161660208301846130f5565b600181815b808511156133d057817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156133b6576133b661316e565b808516156133c357918102915b93841c939080029061337c565b509250929050565b6000826133e757506001610fcb565b816133f457506000610fcb565b816001811461340a576002811461341457613430565b6001915050610fcb565b60ff8411156134255761342561316e565b50506001821b610fcb565b5060208310610133831016604e8410600b8410161715613453575081810a610fcb565b61345d8383613377565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156132665761326661316e565b600061161683836133d8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d820161241456fea2646970667358221220b3b337c9ceb3f8e191b14a91c40b33fb4e8d91c3e456e5e6bcdea6b2f771e7e464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"104929:12592:0:-:0;;;107959:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71739:26;;;;104929:12592;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;104929:12592:0;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"104929:12592:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96501:81;;;;;;;;;;-1:-1:-1;96565:10:0;;96501:81;;;160:25:1;;;148:2;133:18;96501:81:0;;;;;;;;113758:776;;;;;;;;;;-1:-1:-1;113758:776:0;;;;;:::i;:::-;;:::i;:::-;;;1657:14:1;;1650:22;1632:41;;1620:2;1605:18;113758:776:0;1492:187:1;112207:257:0;;;;;;;;;;;;;:::i;:::-;;;;1886:10:1;1874:23;;;1856:42;;1929:2;1914:18;;1907:34;;;;1829:18;112207:257:0;1684:263:1;105811:58:0;;;;;;;;;;;;105860:9;105811:58;;73090:84;;;;;;;;;;;;;:::i;:::-;;96045:32;;;;;;;;;;-1:-1:-1;96045:32:0;;;;;:::i;:::-;;:::i;70537:35::-;;;;;;;;;;;;;;;;;;2493:10:1;2481:23;;;2463:42;;2451:2;2436:18;70537:35:0;2319:192:1;68634:85:0;;;;;;;;;;-1:-1:-1;68706:6:0;;;;68634:85;;;2692:42:1;2680:55;;;2662:74;;2650:2;2635:18;68634:85:0;2516:226:1;109848:140:0;;;;;;;;;;-1:-1:-1;109848:140:0;;;;;:::i;:::-;;:::i;109209:220::-;;;;;;;;;;-1:-1:-1;109209:220:0;;;;;:::i;:::-;;:::i;106084:37::-;;;;;;;;;;-1:-1:-1;106084:37:0;;;;;;;;;;;105988:19;;;;;;;;;;-1:-1:-1;105988:19:0;;;;;;;;72288:133;;;;;;;;;;-1:-1:-1;72288:133:0;;;;;:::i;:::-;;:::i;106160:19::-;;;;;;;;;;-1:-1:-1;106160:19:0;;;;;;;;;;;;;;;;;;:::i;108115:394::-;;;;;;;;;;-1:-1:-1;108115:394:0;;;;;:::i;:::-;;:::i;70692:39::-;;;;;;;;;;-1:-1:-1;70692:39:0;;;;;;;;70663:22;;;;;;;;;;-1:-1:-1;70663:22:0;;;;;;;;96317:81;;;;;;;;;;;;;:::i;69516:198::-;;;;;;;;;;-1:-1:-1;69516:198:0;;;;;:::i;:::-;;:::i;110494:1473::-;;;;;;:::i;:::-;;:::i;96013:26::-;;;;;;;;;;-1:-1:-1;96013:26:0;;;;;;201:33;;;;;;;;;;;;233:1;201:33;;;;;5902:4:1;5890:17;;;5872:36;;5860:2;5845:18;201:33:0;5730:184:1;113758:776:0;113840:4;108927:13;108918:5;;;;;;;:22;;;;;;;;:::i;:::-;;108910:47;;;;-1:-1:-1;;;108910:47:0;;6121:2:1;108910:47:0;;;6103:21:1;6160:2;6140:18;;;6133:30;6199:14;6179:18;;;6172:42;6231:18;;108910:47:0;;;;;;;;;113911:16:::1;113929:13:::0;113946:31:::1;113964:12;113946:17;:31::i;:::-;113910:67;;;;113987:13;114003:24;:5;:22;;;;:24::i;:::-;113987:40:::0;-1:-1:-1;114037:13:0::1;114053:23;-1:-1:-1::0;;114053:21:0;::::1;;:23::i;:::-;114161:15;:22:::0;114037:39;;-1:-1:-1;114152:31:0::1;::::0;::::1;;114148:284;;;114212:15;114228:6;114212:23;;;;;;;;;;:::i;:::-;;;;;;;;;114203:5;:32:::0;114199:139:::1;;-1:-1:-1::0;114318:5:0::1;::::0;113758:776;-1:-1:-1;;;;;113758:776:0:o;114199:139::-:1;114441:7;:5;:7::i;:::-;114463:43;114483:8;114493:12;114463:43;;;;;;;:::i;:::-;;;;;;;;114523:4;114516:11;;;;;;108967:1;113758:776:::0;;;:::o;112207:257::-;112312:15;:22;112255:13;;;;112348:11;;112344:114;;112391:10;112400:1;112391:6;:10;:::i;:::-;112375:27;;112424:15;112440:6;112424:23;;;;;;;;;;:::i;:::-;;;;;;;;;112416:31;;112344:114;112285:179;112207:257;;:::o;73090:84::-;68706:6;;68846:23;68706:6;67634:10;68846:23;68838:68;;;;-1:-1:-1;;;68838:68:0;;7896:2:1;68838:68:0;;;7878:21:1;;;7915:18;;;7908:30;7974:34;7954:18;;;7947:62;8026:18;;68838:68:0;7694:356:1;68838:68:0;73090:84::o;96045:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96045:32:0;:::o;109848:140::-;68706:6;;68846:23;68706:6;67634:10;68846:23;68838:68;;;;-1:-1:-1;;;68838:68:0;;7896:2:1;68838:68:0;;;7878:21:1;;;7915:18;;;7908:30;7974:34;7954:18;;;7947:62;8026:18;;68838:68:0;7694:356:1;68838:68:0;109929:52:::1;109964:15;109929:18;:52::i;:::-;109848:140:::0;:::o;109209:220::-;108723:14;;;;;;;108701:10;:37;108693:65;;;;-1:-1:-1;;;108693:65:0;;8257:2:1;108693:65:0;;;8239:21:1;8296:2;8276:18;;;8269:30;8335:17;8315:18;;;8308:45;8370:18;;108693:65:0;8055:339:1;108693:65:0;109285:21:::1;109297:8;109285:11;:21::i;:::-;-1:-1:-1::0;109401:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;109209:220::o;72288:133::-;68706:6;;68846:23;68706:6;67634:10;68846:23;68838:68;;;;-1:-1:-1;;;68838:68:0;;7896:2:1;68838:68:0;;;7878:21:1;;;7915:18;;;7908:30;7974:34;7954:18;;;7947:62;8026:18;;68838:68:0;7694:356:1;68838:68:0;72380:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;72288:133::o;108115:394::-;61530:19;61552:25;61575:1;61552:22;:25::i;:::-;61530:47;;61591:14;61587:65;;;61621:13;:20;;;;;;;;61587:65;108262:35:::1;108281:15;108262:18;:35::i;:::-;108307:50;108332:14;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108307;:50::i;:::-;108367:5;:21:::0;;;::::1;::::0;::::1;::::0;;108469:15:::1;:33:::0;;-1:-1:-1;108469:33:0;::::1;::::0;;-1:-1:-1;108469:33:0;;;;::::1;::::0;61672:99;;;;61706:13;:21;;;;;;61746:14;;-1:-1:-1;5872:36:1;;61746:14:0;;5860:2:1;5845:18;61746:14:0;;;;;;;;61672:99;61520:257;108115:394;:::o;96317:81::-;96354:7;96380:11;:4;:9;:11::i;:::-;96373:18;;96317:81;:::o;69516:198::-;68706:6;;68846:23;68706:6;67634:10;68846:23;68838:68;;;;-1:-1:-1;;;68838:68:0;;7896:2:1;68838:68:0;;;7878:21:1;;;7915:18;;;7908:30;7974:34;7954:18;;;7947:62;8026:18;;68838:68:0;7694:356:1;68838:68:0;69604:22:::1;::::0;::::1;69596:73;;;::::0;-1:-1:-1;;;69596:73:0;;9056:2:1;69596:73:0::1;::::0;::::1;9038:21:1::0;9095:2;9075:18;;;9068:30;9134:34;9114:18;;;9107:62;9205:8;9185:18;;;9178:36;9231:19;;69596:73:0::1;8854:402:1::0;69596:73:0::1;69679:28;69698:8;69679:18;:28::i;110494:1473::-:0;108927:13;108918:5;;;;;;;:22;;;;;;;;:::i;:::-;;108910:47;;;;-1:-1:-1;;;108910:47:0;;6121:2:1;108910:47:0;;;6103:21:1;6160:2;6140:18;;;6133:30;6199:14;6179:18;;;6172:42;6231:18;;108910:47:0;5919:336:1;108910:47:0;105860:9:::1;110731:12;:19;:45;;110723:70;;;::::0;-1:-1:-1;;;110723:70:0;;9463:2:1;110723:70:0::1;::::0;::::1;9445:21:1::0;9502:2;9482:18;;;9475:30;9541:14;9521:18;;;9514:42;9573:18;;110723:70:0::1;9261:336:1::0;110723:70:0::1;110843:9;110811:28;:16;:5;:14;:16::i;:::-;-1:-1:-1::0;;110811:26:0::1;;:28::i;:::-;:41;;;110803:59;;;::::0;-1:-1:-1;;;110803:59:0;;9804:2:1;110803:59:0::1;::::0;::::1;9786:21:1::0;9843:1;9823:18;;;9816:29;9881:7;9861:18;;;9854:35;9906:18;;110803:59:0::1;9602:328:1::0;110803:59:0::1;110956:5;::::0;:9:::1;::::0;:5:::1;;::::0;:9:::1;:::i;:::-;110948:5;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;110993:41:0::1;111016:17:::0;110993:22:::1;:41::i;:::-;111194:5;::::0;40613:242;;;13561:16:1;40613:242:0;;;13545:102:1;13666:66;111148:11:0::1;13769:3:1::0;13765:16;;;13761:25;;13748:11;;;13741:46;13803:11;;;13796:27;;;13857:16;;;;;13839:12;;;13832:47;13913:16;;;13909:25;;13895:12;;;13888:47;13951:12;;;13944:28;;;14006:16;;;;14002:25;;;13988:12;;;13981:47;40613:242:0;;;;;;;;;14044:12:1;;;;40613:242:0;;110975:59;;-1:-1:-1;111362:21:0::1;111386:51;111408:7;111417:5;111424:12;111386:21;:51::i;:::-;111528:19:::0;;::::1;::::0;::::1;::::0;111362:75;;-1:-1:-1;111610:25:0::1;111528:19:::0;111610:11:::1;:25::i;:::-;111903:5;::::0;::::1;;115910:2:::0;115886:26;;;;;115885:37;111789:171:::1;;111847:1;111837:7;96565:10:::0;;;96501:81;111837:7:::1;:11;;;;:::i;:::-;111811:12;111789:171;111923:5;111942:8;111789:171;;;;;;;:::i;:::-;;;;;;;;110713:1254;;;;110494:1473:::0;;;;;:::o;79198:474::-;79299:16;;79354:19;:12;79299:16;79354;:19::i;:::-;79346:27;-1:-1:-1;73871:2:0;3639:26;17461:2;17457:16;;;17453:28;75125:37;79383:52;;;;-1:-1:-1;;;79383:52:0;;10752:2:1;79383:52:0;;;10734:21:1;10791:2;10771:18;;;10764:30;10830:20;10810:18;;;10803:48;10868:18;;79383:52:0;10550:342:1;79383:52:0;79456:115;79488:23;-1:-1:-1;;79488:21:0;;;:23::i;:::-;79525:36;:28;-1:-1:-1;;79525:26:0;;;:28::i;:::-;-1:-1:-1;;79525:34:0;;:36::i;:::-;79456:18;:115::i;:::-;79445:126;-1:-1:-1;79589:47:0;79600:25;-1:-1:-1;;79600:23:0;;;:25::i;:::-;79627:8;79589:10;:47::i;:::-;79581:84;;;;-1:-1:-1;;;79581:84:0;;11099:2:1;79581:84:0;;;11081:21:1;11138:2;11118:18;;;11111:30;11177:26;11157:18;;;11150:54;11221:18;;79581:84:0;10897:348:1;79581:84:0;79198:474;;;:::o;75523:136::-;75587:6;75619:32;-1:-1:-1;;75619:15:0;;73765:1;;75619:15;:32::i;:::-;75605:47;75523:136;-1:-1:-1;;75523:136:0:o;75752:124::-;75815:7;75841:28;-1:-1:-1;;75841:11:0;;73812:1;75866:2;75841:11;:28::i;115156:231::-;115226:5;:21;;;;;;;;;;;;115282:48;;;;;115318:10;115282:14;:48;;2662:74:1;115282:14:0;;;;;;;;;;:27;;2635:18:1;;115282:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;115360:7:0;;115345:35;;115369:10;;-1:-1:-1;115345:35:0;115360:7;;;;-1:-1:-1;115345:35:0;;115360:7;;115345:35;115156:231::o;114708:285::-;98137:19;;;;114788:81;;;;-1:-1:-1;;;114788:81:0;;11699:2:1;114788:81:0;;;11681:21:1;11738:2;11718:18;;;11711:30;11777:26;11757:18;;;11750:54;11821:18;;114788:81:0;11497:348:1;114788:81:0;114879:14;:49;;;;;;;;;;;;;;;;;;114943:43;;2662:74:1;;;114943:43:0;;2650:2:1;2635:18;114943:43:0;;;;;;;114708:285;:::o;72718:179::-;72801:7;;;;72818:21;;;;;;;;;;;72854:36;;;72801:7;;;;12085:34:1;;;12150:2;12135:18;;12128:43;;;;72854:36:0;;11997:18:1;72854:36:0;11850:327:1;63706:808:0;64103:13;;63770:4;;64103:13;;;;;64099:409;;;64157:7;:12;;64168:1;64157:12;:61;;;;-1:-1:-1;64212:4:0;98137:19;:23;64157:61;64132:166;;;;-1:-1:-1;;;64132:166:0;;12384:2:1;64132:166:0;;;12366:21:1;12423:2;12403:18;;;12396:30;12462:34;12442:18;;;12435:62;12533:16;12513:18;;;12506:44;12567:19;;64132:166:0;12182:410:1;64132:166:0;-1:-1:-1;64319:5:0;;63706:808;-1:-1:-1;63706:808:0:o;64099:409::-;64363:12;;:22;;;;:12;;:22;64355:81;;;;-1:-1:-1;;;64355:81:0;;12384:2:1;64355:81:0;;;12366:21:1;12423:2;12403:18;;;12396:30;12462:34;12442:18;;;12435:62;12533:16;12513:18;;;12506:44;12567:19;;64355:81:0;12182:410:1;64355:81:0;-1:-1:-1;64450:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;63706:808:0:o;71824:142::-;63117:13;;;;;;;63109:69;;;;-1:-1:-1;;;63109:69:0;;12799:2:1;63109:69:0;;;12781:21:1;12838:2;12818:18;;;12811:30;12877:34;12857:18;;;12850:62;12948:13;12928:18;;;12921:41;12979:19;;63109:69:0;12597:407:1;63109:69:0;71912:16:::1;:14;:16::i;:::-;71938:21;71950:8;71938:11;:21::i;82785:122::-:0;82842:7;82868:32;82880:5;82887:12;:10;:12::i;:::-;82868:11;:32::i;69868:187::-;69960:6;;;;69976:17;;;;;;;;;;;70008:40;;69960:6;;;69976:17;69960:6;;70008:40;;69941:16;;70008:40;69931:124;69868:187;:::o;90373:122::-;90434:7;90460:28;:5;35057:10;90460:9;:28::i;91480:183::-;91553:6;91537:5;89380:35;35057:10;35050:18;-1:-1:-1;;89380:16:0;;;;:35::i;:::-;;91637:19:::1;91650:5;91637:12;:19::i;:::-;91618:16;91628:5;91618:9;:16::i;:::-;91598:17;91609:5;91598:10;:17::i;:::-;91578;91589:5;91578:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;91571:85;;89425:1;91480:183:::0;;;;:::o;116705:814::-;116811:14;92298:24;116845:48;;116841:672;;116945:10;116909:47;113758:776;-1:-1:-1;;113758:776:0:o;116841:672::-;117349:24;:22;:24::i;:::-;-1:-1:-1;92298:24:0;116705:814;;;:::o;36242:638::-;36538:14;;36387:12;;36495:17;;35993:29;36011:10;35864:1;35993:29;:::i;:::-;36515:13;;:38;;;;:::i;:::-;36495:58;;36563:17;36603:5;:12;36583:10;:33;;;;:::i;:::-;36563:53;-1:-1:-1;34714:1:0;35993:29;36011:10;35864:1;35993:29;:::i;:::-;36712:13;;36743:10;36771;36799:7;36824:5;36847:12;36645:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;36626:247;;;;36242:638;;;;;;:::o;96739:123::-;96794:18;:4;96806:5;96794:11;:18::i;:::-;96822:15;96843:11;:4;:9;:11::i;:::-;96822:33;;;;;;;-1:-1:-1;96822:33:0;;;;;;;;;;;-1:-1:-1;96739:123:0:o;14624:359::-;14728:10;;14694:7;;14875:4;14866:14;;14950:26;;;;14866:14;14728:10;14950:5;:26::i;:::-;14943:33;14624:359;-1:-1:-1;;;;;14624:359:0:o;75982:155::-;76045:7;76071:59;-1:-1:-1;;76071:11:0;;76045:7;73871:2;76045:7;76071:11;:59::i;76220:172::-;76288:7;76314:71;73871:2;76344:37;73871:2;17461;17457:16;;;3639:26;17453:28;76344:37;:::i;:::-;-1:-1:-1;;76314:11:0;;;:71;76383:1;76314:11;:71::i;29277:632::-;29332:16;29360:11;29381:12;29396;29400:7;17461:2;17457:16;3639:26;17453:28;;17215:282;29396:12;29381:27;;;;29518:4;29512:11;29505:18;;29573:3;29566:10;;29619:33;29632:7;29641:3;29647:4;29641:10;29619:12;:33::i;:::-;-1:-1:-1;29776:14:0;;;29792:4;29772:25;29766:4;29759:39;29839:17;;29277:632;;-1:-1:-1;29277:632:0:o;76719:285::-;76829:14;;76876;-1:-1:-1;;76876:12:0;;;:14::i;:::-;76859:31;;76909:36;76938:6;52454:58;;21311:66:1;52454:58:0;;;21299:79:1;21394:12;;;21387:28;;;52324:7:0;;21431:12:1;;52454:58:0;;;;;;;;;;;;52444:69;;;;;;52437:76;;52255:265;;;;76909:36;76900:45;;76964:33;76978:6;76986:10;76964:13;:33::i;:::-;76955:42;76719:285;-1:-1:-1;;;;76719:285:0:o;75266:143::-;75331:6;75363:38;-1:-1:-1;;75363:15:0;;75331:6;75399:1;75363:15;:38::i;115935:236::-;116057:4;116100:11;116085:26;;:11;:26;;;116077:51;;;;-1:-1:-1;;;116077:51:0;;15819:2:1;116077:51:0;;;15801:21:1;15858:2;15838:18;;;15831:30;15897:14;15877:18;;;15870:42;15929:18;;116077:51:0;15617:336:1;116077:51:0;-1:-1:-1;116157:7:0;;;;;;116145:19;;;;115935:236;-1:-1:-1;115935:236:0:o;22090:221::-;22209:14;22287:11;22292:6;22287:2;:11;:::i;:::-;22286:17;;22302:1;22286:17;:::i;:::-;22242:62;;22250:30;22256:7;22265:6;22273;22250:5;:30::i;:::-;22242:62;;;22090:221;-1:-1:-1;;;;22090:221:0:o;20973:771::-;21088:14;21118:6;:11;;21128:1;21118:11;21114:59;;-1:-1:-1;21160:1:0;21145:17;;21114:59;21204:12;21208:7;17461:2;17457:16;3639:26;17453:28;;17215:282;21204:12;21186:30;;:15;;;;:6;:15;:::i;:::-;:30;21182:137;;;21239:68;21255:12;21259:7;16355:3;16351:17;3639:26;16347:29;;16028:364;21255:12;21239:68;;21269:12;21273:7;17461:2;17457:16;3639:26;17453:28;;17215:282;21269:12;21239:68;;21283:6;21299;21291:15;;21239;:68::i;:::-;21232:76;;-1:-1:-1;;;21232:76:0;;;;;;;;:::i;21182:137::-;21346:2;21336:6;:12;;;;21328:83;;;;-1:-1:-1;;;21328:83:0;;16717:2:1;21328:83:0;;;16699:21:1;16756:2;16736:18;;;16729:30;16795:34;16775:18;;;16768:62;16866:28;16846:18;;;16839:56;16912:19;;21328:83:0;16515:422:1;21328:83:0;21492:1;21483:10;;21422:15;21528:12;21532:7;16355:3;16351:17;3639:26;16347:29;;16028:364;21528:12;21513:27;;;-1:-1:-1;21550:13:0;8457:66;8427:12;;;8406:131;21702:17;;;;21696:24;21692:36;;;-1:-1:-1;;;;;20973:771:0:o;68346:95::-;63117:13;;;;;;;63109:69;;;;-1:-1:-1;;;63109:69:0;;12799:2:1;63109:69:0;;;12781:21:1;12838:2;12818:18;;;12811:30;12877:34;12857:18;;;12850:62;12948:13;12928:18;;;12921:41;12979:19;;63109:69:0;12597:407:1;63109:69:0;68408:26:::1;:24;:26::i;83025:964::-:0;83070:34;;:::i;:::-;83129:3;83116:16;;83155:3;83116:10;83142;;:16;83181:3;83168:10;;;:16;83207:3;83194:10;;;:16;83233:3;83220:10;;;:16;83259:3;83246:10;;;:16;83285:3;83272:10;;;:16;83311:3;83298:10;;;:16;83337:3;83324:10;;;:16;83363:3;83350:10;;;:16;83390:4;83376:11;;;:18;83418:4;83404:11;;;:18;83446:4;83432:11;;;:18;83474:4;83460:11;;;:18;83502:4;83488:11;;;:18;83530:4;83516:11;;;:18;83558:4;83544:11;;;:18;83586:4;83572:11;;;:18;83614:4;83600:11;;;:18;83642:4;83628:11;;;:18;83670:4;83656:11;;;:18;83698:4;83684:11;;;:18;83726:4;83712:11;;;:18;83754:4;83740:11;;;:18;83782:4;83768:11;;;:18;83810:4;83796:11;;;:18;83838:4;83824:11;;;:18;83866:4;83852:11;;;:18;83894:4;83880:11;;;:18;83922:4;83908:11;;;:18;83950:4;83936:11;;;:18;83978:4;83964:11;;;:18;83116:7;83025:964::o;82129:589::-;82302:11;;;;82253:16;;;82324:388;80709:2;82344:1;:14;82324:388;;;82410:4;82395:11;;;82394:20;;;82432:12;;;82428:215;;82502:5;82515:1;82502:15;;;;;;;:::i;:::-;;;82485:43;;;;;;17099:19:1;;;;17134:12;;17127:28;;;17171:12;;82485:43:0;;;;;;;;;;;;82475:54;;;;;;82464:65;;82428:215;;;82606:8;82616:7;82624:1;82616:10;;;;;;;:::i;:::-;;;;;82589:38;;;;;;;;17099:19:1;;;17143:2;17134:12;;17127:28;17180:2;17171:12;;16942:247;82589:38:0;;;;;;;;;;;;;82579:49;;;;;;82568:60;;82428:215;-1:-1:-1;82684:3:0;;82324:388;;;;82275:443;82129:589;;;;:::o;11042:578::-;11120:7;11144:26;11151:7;11160:9;11144:6;:26::i;:::-;11139:451;;11189:9;11202:35;11220:15;11227:7;15386:3;15382:17;;15175:268;11220:15;11212:24;;11202:9;:35::i;:::-;11186:51;;;11254:9;11267:29;11285:9;11277:18;;11267:9;:29::i;:::-;11354:186;;17561:31:1;11354:186:0;;;17549:44:1;17612:66;17716:3;17712:16;;;17708:25;;17694:12;;;17687:47;17764:15;17750:12;;;17743:37;17814:16;;;17810:25;17796:12;;;17789:47;11251:45:0;;-1:-1:-1;11310:17:0;;-1:-1:-1;17852:12:1;;11354:186:0;;;;;;;;;;;;11310:244;;11575:3;11568:11;;-1:-1:-1;;;11568:11:0;;;;;;;;:::i;11139:451::-;-1:-1:-1;11606:7:0;;11042:578;-1:-1:-1;11042:578:0:o;91321:153::-;91397:6;91381:5;89380:35;35057:10;35050:18;;89380:35;-1:-1:-1;91429:37:0::1;-1:-1:-1::0;;91429:15:0;::::1;89328:2;91463;91429:15;:37::i;:::-;91415:52;;::::0;91321:153;-1:-1:-1;;;91321:153:0:o;91125:147::-;91198:6;91182:5;89380:35;35057:10;35050:18;;89380:35;-1:-1:-1;91230:34:0::1;-1:-1:-1::0;;91230:15:0;::::1;89275:2;91261;91230:15;:34::i;90930:149::-:0;91004:6;90988:5;89380:35;35057:10;35050:18;;89380:35;-1:-1:-1;91036:35:0::1;-1:-1:-1::0;;91036:15:0;::::1;89225:2;91068;91036:15;:35::i;90734:149::-:0;90808:6;90792:5;89380:35;35057:10;35050:18;;89380:35;-1:-1:-1;90840:35:0::1;-1:-1:-1::0;;90840:15:0;::::1;89175:1;90872:2;90840:15;:35::i;72480:132::-:0;72568:15;;;;72546:10;:38;72538:67;;;;-1:-1:-1;;;72538:67:0;;18077:2:1;72538:67:0;;;18059:21:1;18116:2;18096:18;;;18089:30;18155:18;18135;;;18128:46;18191:18;;72538:67:0;17875:340:1;81168:750:0;81253:11;;;;;;80772:1;;80756:13;;:1;:13;:::i;:::-;:17;;;;:::i;:::-;81282:4;:17;81274:46;;;;-1:-1:-1;;;81274:46:0;;19916:2:1;81274:46:0;;;19898:21:1;19955:2;19935:18;;;19928:30;19994:18;19974;;;19967:46;20030:18;;81274:46:0;19714:340:1;81274:46:0;81355:6;;81381:11;;;:18;;;81414:9;81409:319;80709:2;81429:1;:14;81409:319;;;81466:4;81473:1;81466:8;81479:1;81465:15;81461:101;;81518:5;81500;81513:1;81500:15;;;;;;;:::i;:::-;;:23;-1:-1:-1;;;;81168:750:0:o;81461:101::-;81610:5;81623:1;81610:15;;;;;;;:::i;:::-;;;81593:40;;;;;;17099:19:1;;;;17134:12;;17127:28;;;17171:12;;81593:40:0;;;;;;;;;;;;;81583:51;;81593:40;81583:51;;;;;-1:-1:-1;81657:1:0;81648:10;;;;81700:3;81409:319;;;-1:-1:-1;81898:13:0;;:::i;:::-;81228:690;81168:750;;:::o;13765:462::-;13876:15;;13918:11;13925:4;13918;:11;:::i;:::-;13903:26;;14044:4;14038:11;14032:4;14029:21;14026:66;;;-1:-1:-1;14077:1:0;14026:66;14115:4;14123:1;14115:9;14111:51;;-1:-1:-1;;14140:11:0;;;;;14111:51;-1:-1:-1;;13034:2:0;13030:27;;;13104:17;;;;13096:26;;;13168:17;13164:2;13160:26;;13765:462::o;18098:399::-;18237:7;18256:12;18271;18275:7;16355:3;16351:17;3639:26;16347:29;;16028:364;18271:12;18256:27;;;;18367:12;18371:7;18367:3;:12::i;:::-;18360:4;18344:13;18351:6;18344:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;18340:77;;;-1:-1:-1;;18395:11:0;;;;;18340:77;18434:13;18441:6;18434:4;:13;:::i;:::-;18427:20;;18464:26;18470:7;18464:26;;18479:4;18485;18464:5;:26::i;:::-;18457:33;18098:399;-1:-1:-1;;;;;;18098:399:0:o;28005:902::-;28083:15;-1:-1:-1;;8941:15:0;;;;28110:69;;;;-1:-1:-1;;;28110:69:0;;20450:2:1;28110:69:0;;;20432:21:1;20489:2;20469:18;;;20462:30;20528:34;20508:18;;;20501:62;20599:10;20579:18;;;20572:38;20627:19;;28110:69:0;20248:404:1;28110:69:0;28197:16;28205:7;28197;:16::i;:::-;28189:72;;;;-1:-1:-1;;;28189:72:0;;20859:2:1;28189:72:0;;;20841:21:1;20898:2;20878:18;;;20871:30;20937:34;20917:18;;;20910:62;21008:13;20988:18;;;20981:41;21039:19;;28189:72:0;20657:407:1;28189:72:0;28271:12;28286;28290:7;17461:2;17457:16;3639:26;17453:28;;17215:282;28286:12;28271:27;;;;28308:15;28326:12;28330:7;16355:3;16351:17;3639:26;16347:29;;16028:364;28326:12;28308:30;;;;28349:11;28470:4;28464:11;28457:18;;28557:7;28552:3;28549:16;28546:94;;;28597:4;28591;28584:18;28546:94;28812:4;28803:7;28797:4;28788:7;28785:1;28778:5;28767:50;28763:55;28848:52;28869:15;28876:7;15386:3;15382:17;;15175:268;28869:15;13030:27;13034:2;13030:27;;;;13104:17;;13096:26;;13168:17;;13164:2;13160:26;;12780:446;23424:290;23480:14;23506:12;23521;23525:7;16355:3;16351:17;3639:26;16347:29;;16028:364;23521:12;23506:27;;;;23543:12;23558;23562:7;17461:2;17457:16;3639:26;17453:28;;17215:282;23558:12;23543:27;;23677:21;;;;23424:290;-1:-1:-1;;;23424:290:0:o;48551:227::-;48629:7;48649:17;48668:18;48690:27;48701:4;48707:9;48690:10;:27::i;:::-;48648:69;;;;48727:18;48739:5;48727:11;:18::i;:::-;-1:-1:-1;48762:9:0;48551:227;-1:-1:-1;;;48551:227:0:o;19730:741::-;19876:17;19908:9;19921:15;19931:4;19921:9;:15::i;:::-;19905:31;;;19949:9;19962:15;19972:4;19962:9;:15::i;:::-;19946:31;;;19990:9;20003:17;20013:6;20003:9;:17::i;:::-;19987:33;;;20033:9;20046:17;20056:6;20046:9;:17::i;:::-;20030:33;;;20213:1;20275;20355;20417;20099:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;20073:391;;19895:576;;;;19730:741;;;;;;:::o;68447:111::-;63117:13;;;;;;;63109:69;;;;-1:-1:-1;;;63109:69:0;;12799:2:1;63109:69:0;;;12781:21:1;12838:2;12818:18;;;12811:30;12877:34;12857:18;;;12850:62;12948:13;12928:18;;;12921:41;12979:19;;63109:69:0;12597:407:1;63109:69:0;68519:32:::1;67634:10:::0;68519:18:::1;:32::i;10612:132::-:0;10686:4;10728:9;10709:28;;:15;10716:7;15386:3;15382:17;;15175:268;10709:15;:28;;;;10612:132;-1:-1:-1;;;10612:132:0:o;6000:667::-;6054:13;;6110:2;6095:258;6118:2;6114:1;:6;;;6095:258;;;6138:11;6165:5;:1;6169;6165:5;:::i;:::-;6158:13;;:2;:13;;6138:34;;6195:14;6203:5;6195:7;:14::i;:::-;6186:23;;;;;;6227:1;:7;;6232:2;6227:7;6223:58;;6264:2;6254:12;;;;;6223:58;-1:-1:-1;6322:6:0;;6095:258;;;-1:-1:-1;6416:2:0;6401:260;6424:3;6420:1;:7;;;6401:260;;;6445:11;6472:5;:1;6476;6472:5;:::i;:::-;6465:13;;:2;:13;;6445:34;;6503:14;6511:5;6503:7;:14::i;:::-;6493:24;;;;;;6535:1;:6;;6540:1;6535:6;6531:58;;6572:2;6561:13;;;;;6531:58;-1:-1:-1;6630:6:0;;6401:260;;;;6000:667;;;:::o;17671:147::-;17724:7;17789:12;17793:7;17461:2;17457:16;3639:26;17453:28;;17215:282;17789:12;17774;17778:7;16355:3;16351:17;3639:26;16347:29;;16028:364;17774:12;:27;17767:34;;;;17671:147;;;:::o;9614:333::-;9671:8;9695:15;9702:7;15386:3;15382:17;;15175:268;9695:15;:31;;9714:12;9695:31;9691:74;;-1:-1:-1;9749:5:0;;9614:333;-1:-1:-1;9614:333:0:o;9691:74::-;9774:12;9789;9793:7;9789:3;:12::i;:::-;9924:4;9918:11;-1:-1:-1;9905:26:0;;9614:333;-1:-1:-1;;;9614:333:0:o;46486:1279::-;46567:7;46576:12;46797:9;:16;46817:2;46797:22;46793:966;;47086:4;47071:20;;47065:27;47135:4;47120:20;;47114:27;47192:4;47177:20;;47171:27;46835:9;47163:36;47233:25;47244:4;47163:36;47065:27;47114;47233:10;:25::i;:::-;47226:32;;;;;;;;;46793:966;47279:9;:16;47299:2;47279:22;47275:484;;47548:4;47533:20;;47527:27;47598:4;47583:20;;47577:27;47638:23;47649:4;47527:27;47577;47638:10;:23::i;:::-;47631:30;;;;;;;;47275:484;-1:-1:-1;47708:1:0;;-1:-1:-1;47712:35:0;47275:484;46486:1279;;;;;:::o;44791:631::-;44868:20;44859:5;:29;;;;;;;;:::i;:::-;;44855:561;;44791:631;:::o;44855:561::-;44964:29;44955:5;:38;;;;;;;;:::i;:::-;;44951:465;;45009:34;;-1:-1:-1;;;45009:34:0;;23171:2:1;45009:34:0;;;23153:21:1;23210:2;23190:18;;;23183:30;23249:26;23229:18;;;23222:54;23293:18;;45009:34:0;22969:348:1;44951:465:0;45073:35;45064:5;:44;;;;;;;;:::i;:::-;;45060:356;;45124:41;;-1:-1:-1;;;45124:41:0;;23524:2:1;45124:41:0;;;23506:21:1;23563:2;23543:18;;;23536:30;23602:33;23582:18;;;23575:61;23653:18;;45124:41:0;23322:355:1;45060:356:0;45195:30;45186:5;:39;;;;;;;;:::i;:::-;;45182:234;;45241:44;;-1:-1:-1;;;45241:44:0;;23884:2:1;45241:44:0;;;23866:21:1;23923:2;23903:18;;;23896:30;23962:34;23942:18;;;23935:62;24033:4;24013:18;;;24006:32;24055:19;;45241:44:0;23682:398:1;45182:234:0;45315:30;45306:5;:39;;;;;;;;:::i;:::-;;45302:114;;45361:44;;-1:-1:-1;;;45361:44:0;;24287:2:1;45361:44:0;;;24269:21:1;24326:2;24306:18;;;24299:30;24365:34;24345:18;;;24338:62;24436:4;24416:18;;;24409:32;24458:19;;45361:44:0;24085:398:1;5477:199:0;5527:14;5564:18;5580:1;5574:2;:7;;;;5564:9;:18::i;:::-;5553:29;;5606:13;;;;;;5618:1;5606:13;5640;5650:2;5640:9;:13::i;:::-;5629:24;;;;5477:199;-1:-1:-1;5477:199:0:o;49959:1603::-;50085:7;;51009:66;50996:79;;50992:161;;;-1:-1:-1;51107:1:0;;-1:-1:-1;51111:30:0;51091:51;;50992:161;51166:1;:7;;51171:2;51166:7;;:18;;;;;51177:1;:7;;51182:2;51177:7;;51166:18;51162:100;;;-1:-1:-1;51216:1:0;;-1:-1:-1;51220:30:0;51200:51;;51162:100;51373:24;;;51356:14;51373:24;;;;;;;;;24715:25:1;;;24788:4;24776:17;;24756:18;;;24749:45;;;;24810:18;;;24803:34;;;24853:18;;;24846:34;;;51373:24:0;;24687:19:1;;51373:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;51373:24:0;;;;;;-1:-1:-1;;51411:20:0;;;51407:101;;51463:1;51467:29;51447:50;;;;;;;51407:101;51526:6;-1:-1:-1;51534:20:0;;-1:-1:-1;49959:1603:0;;;;;;;;:::o;49032:336::-;49142:7;;49200:66;49187:80;;49142:7;49293:25;49309:3;49294:18;;;49316:2;49293:25;:::i;:::-;49277:42;;49336:25;49347:4;49353:1;49356;49359;49336:10;:25::i;:::-;49329:32;;;;;;49032:336;;;;;;:::o;3912:1393::-;3964:10;4130:4;4125:9;;;;4176:15;;;;;4172:57;;-1:-1:-1;4214:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4172:57::-;4247:7;:15;;4258:4;4247:15;4243:57;;-1:-1:-1;4285:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4243:57::-;4318:7;:15;;4329:4;4318:15;4314:57;;-1:-1:-1;4356:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4314:57::-;4389:7;:15;;4400:4;4389:15;4385:57;;-1:-1:-1;4427:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4385:57::-;4460:7;:15;;4471:4;4460:15;4456:57;;-1:-1:-1;4498:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4456:57::-;4531:7;:15;;4542:4;4531:15;4527:57;;-1:-1:-1;4569:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4527:57::-;4602:7;:15;;4613:4;4602:15;4598:57;;-1:-1:-1;4640:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4598:57::-;4673:7;:15;;4684:4;4673:15;4669:57;;-1:-1:-1;4711:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4669:57::-;4744:7;:15;;4755:4;4744:15;4740:57;;-1:-1:-1;4782:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4740:57::-;4815:7;:15;;4826:4;4815:15;4811:57;;-1:-1:-1;4853:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4811:57::-;4886:7;:15;;4897:4;4886:15;4882:57;;-1:-1:-1;4924:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4882:57::-;4957:7;:15;;4968:4;4957:15;4953:57;;-1:-1:-1;4995:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;4953:57::-;5028:7;:15;;5039:4;5028:15;5024:57;;-1:-1:-1;5066:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;5024:57::-;5099:7;:15;;5110:4;5099:15;5095:57;;-1:-1:-1;5137:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;5095:57::-;5170:7;:15;;5181:4;5170:15;5166:57;;-1:-1:-1;5208:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;5166:57::-;5241:7;:15;;5252:4;5241:15;5237:57;;-1:-1:-1;5279:4:0;;3912:1393;-1:-1:-1;;3912:1393:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:184:1:-;248:77;245:1;238:88;345:4;342:1;335:15;369:4;366:1;359:15;385:777;427:5;480:3;473:4;465:6;461:17;457:27;447:55;;498:1;495;488:12;447:55;534:6;521:20;560:18;597:2;593;590:10;587:36;;;603:18;;:::i;:::-;737:2;731:9;799:4;791:13;;642:66;787:22;;;811:2;783:31;779:40;767:53;;;835:18;;;855:22;;;832:46;829:72;;;881:18;;:::i;:::-;921:10;917:2;910:22;956:2;948:6;941:18;1002:3;995:4;990:2;982:6;978:15;974:26;971:35;968:55;;;1019:1;1016;1009:12;968:55;1083:2;1076:4;1068:6;1064:17;1057:4;1049:6;1045:17;1032:54;1130:1;1123:4;1118:2;1110:6;1106:15;1102:26;1095:37;1150:6;1141:15;;;;;;385:777;;;;:::o;1167:320::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;1344:9;1331:23;1377:18;1369:6;1366:30;1363:50;;;1409:1;1406;1399:12;1363:50;1432:49;1473:7;1464:6;1453:9;1449:22;1432:49;:::i;1952:180::-;2011:6;2064:2;2052:9;2043:7;2039:23;2035:32;2032:52;;;2080:1;2077;2070:12;2032:52;-1:-1:-1;2103:23:1;;1952:180;-1:-1:-1;1952:180:1:o;2747:154::-;2833:42;2826:5;2822:54;2815:5;2812:65;2802:93;;2891:1;2888;2881:12;2906:247;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3073:9;3060:23;3092:31;3117:5;3092:31;:::i;3686:184::-;3738:77;3735:1;3728:88;3835:4;3832:1;3825:15;3859:4;3856:1;3849:15;3875:396;4018:2;4003:18;;4051:1;4040:13;;4030:201;;4087:77;4084:1;4077:88;4188:4;4185:1;4178:15;4216:4;4213:1;4206:15;4030:201;4240:25;;;3875:396;:::o;4804:163::-;4871:20;;4931:10;4920:22;;4910:33;;4900:61;;4957:1;4954;4947:12;4972:753;5083:6;5091;5099;5107;5115;5168:3;5156:9;5147:7;5143:23;5139:33;5136:53;;;5185:1;5182;5175:12;5136:53;5208:28;5226:9;5208:28;:::i;:::-;5198:38;;5283:2;5272:9;5268:18;5255:32;5245:42;;5306:37;5339:2;5328:9;5324:18;5306:37;:::i;:::-;5296:47;;5394:2;5383:9;5379:18;5366:32;5417:18;5458:2;5450:6;5447:14;5444:34;;;5474:1;5471;5464:12;5444:34;5497:49;5538:7;5529:6;5518:9;5514:22;5497:49;:::i;:::-;5487:59;;5599:3;5588:9;5584:19;5571:33;5555:49;;5629:2;5619:8;5616:16;5613:36;;;5645:1;5642;5635:12;5613:36;;5668:51;5711:7;5700:8;5689:9;5685:24;5668:51;:::i;:::-;5658:61;;;4972:753;;;;;;;;:::o;6260:184::-;6312:77;6309:1;6302:88;6409:4;6406:1;6399:15;6433:4;6430:1;6423:15;6449:258;6521:1;6531:113;6545:6;6542:1;6539:13;6531:113;;;6621:11;;;6615:18;6602:11;;;6595:39;6567:2;6560:10;6531:113;;;6662:6;6659:1;6656:13;6653:48;;;6697:1;6688:6;6683:3;6679:16;6672:27;6653:48;;6449:258;;;:::o;6712:316::-;6753:3;6791:5;6785:12;6818:6;6813:3;6806:19;6834:63;6890:6;6883:4;6878:3;6874:14;6867:4;6860:5;6856:16;6834:63;:::i;:::-;6942:2;6930:15;6947:66;6926:88;6917:98;;;;7017:4;6913:109;;6712:316;-1:-1:-1;;6712:316:1:o;7033:337::-;7220:42;7212:6;7208:55;7197:9;7190:74;7300:2;7295;7284:9;7280:18;7273:30;7171:4;7320:44;7360:2;7349:9;7345:18;7337:6;7320:44;:::i;7375:184::-;7427:77;7424:1;7417:88;7524:4;7521:1;7514:15;7548:4;7545:1;7538:15;7564:125;7604:4;7632:1;7629;7626:8;7623:34;;;7637:18;;:::i;:::-;-1:-1:-1;7674:9:1;;7564:125::o;8399:251::-;8469:6;8522:2;8510:9;8501:7;8497:23;8493:32;8490:52;;;8538:1;8535;8528:12;8490:52;8570:9;8564:16;8589:31;8614:5;8589:31;:::i;9935:228::-;9974:3;10002:10;10039:2;10036:1;10032:10;10069:2;10066:1;10062:10;10100:3;10096:2;10092:12;10087:3;10084:21;10081:47;;;10108:18;;:::i;:::-;10144:13;;9935:228;-1:-1:-1;;;;9935:228:1:o;10168:377::-;10361:2;10350:9;10343:21;10324:4;10387:44;10427:2;10416:9;10412:18;10404:6;10387:44;:::i;:::-;10479:9;10471:6;10467:22;10462:2;10451:9;10447:18;10440:50;10507:32;10532:6;10524;10507:32;:::i;13009:244::-;13048:3;13076:26;13129:2;13126:1;13122:10;13159:2;13156:1;13152:10;13190:3;13186:2;13182:12;13177:3;13174:21;13171:47;;;13198:18;;:::i;14067:238::-;14105:7;14145:4;14142:1;14138:12;14177:4;14174:1;14170:12;14237:3;14231:4;14227:14;14222:3;14219:23;14212:3;14205:11;14198:19;14194:49;14191:75;;;14246:18;;:::i;:::-;14286:13;;14067:238;-1:-1:-1;;;14067:238:1:o;14310:224::-;14349:3;14377:6;14410:2;14407:1;14403:10;14440:2;14437:1;14433:10;14471:3;14467:2;14463:12;14458:3;14455:21;14452:47;;;14479:18;;:::i;14539:1073::-;14864:3;14892:66;15001:2;14992:6;14987:3;14983:16;14979:25;14974:3;14967:38;15056:2;15047:6;15042:3;15038:16;15034:25;15030:1;15025:3;15021:11;15014:46;15111:2;15102:6;15097:3;15093:16;15089:25;15085:1;15080:3;15076:11;15069:46;15166:2;15157:6;15152:3;15148:16;15144:25;15140:1;15135:3;15131:11;15124:46;;15199:6;15193:13;15215:61;15269:6;15265:1;15260:3;15256:11;15249:4;15241:6;15237:17;15215:61;:::i;:::-;15336:13;;15295:16;;;;15358:62;15336:13;15407:1;15399:10;;15392:4;15380:17;;15358:62;:::i;:::-;15481:13;;15439:17;;;15503:62;15481:13;15552:1;15544:10;;15537:4;15525:17;;15503:62;:::i;:::-;15585:17;15604:1;15581:25;;14539:1073;-1:-1:-1;;;;;;;;;14539:1073:1:o;15958:195::-;15996:4;16033;16030:1;16026:12;16065:4;16062:1;16058:12;16090:3;16085;16082:12;16079:38;;;16097:18;;:::i;:::-;16134:13;;;15958:195;-1:-1:-1;;;15958:195:1:o;16158:128::-;16198:3;16229:1;16225:6;16222:1;16219:13;16216:39;;;16235:18;;:::i;:::-;-1:-1:-1;16271:9:1;;16158:128::o;16291:219::-;16440:2;16429:9;16422:21;16403:4;16460:44;16500:2;16489:9;16485:18;16477:6;16460:44;:::i;18220:482::-;18309:1;18352:5;18309:1;18366:330;18387:7;18377:8;18374:21;18366:330;;;18506:4;18438:66;18434:77;18428:4;18425:87;18422:113;;;18515:18;;:::i;:::-;18565:7;18555:8;18551:22;18548:55;;;18585:16;;;;18548:55;18664:22;;;;18624:15;;;;18366:330;;;18370:3;18220:482;;;;;:::o;18707:866::-;18756:5;18786:8;18776:80;;-1:-1:-1;18827:1:1;18841:5;;18776:80;18875:4;18865:76;;-1:-1:-1;18912:1:1;18926:5;;18865:76;18957:4;18975:1;18970:59;;;;19043:1;19038:130;;;;18950:218;;18970:59;19000:1;18991:10;;19014:5;;;19038:130;19075:3;19065:8;19062:17;19059:43;;;19082:18;;:::i;:::-;-1:-1:-1;;19138:1:1;19124:16;;19153:5;;18950:218;;19252:2;19242:8;19239:16;19233:3;19227:4;19224:13;19220:36;19214:2;19204:8;19201:16;19196:2;19190:4;19187:12;19183:35;19180:77;19177:159;;;-1:-1:-1;19289:19:1;;;19321:5;;19177:159;19368:34;19393:8;19387:4;19368:34;:::i;:::-;19498:6;19430:66;19426:79;19417:7;19414:92;19411:118;;;19509:18;;:::i;19578:131::-;19638:5;19667:36;19694:8;19688:4;19667:36;:::i;20059:184::-;20111:77;20108:1;20101:88;20208:4;20205:1;20198:15;20232:4;20229:1;20222:15;21573:1391;22295:34;22283:47;;22360:23;22355:2;22346:12;;22339:45;22403:66;22507:3;22503:16;;;22499:25;;22494:2;22485:12;;22478:47;22544:17;22586:2;22577:12;;22570:24;;;22628:16;;;22624:25;;22619:2;22610:12;;22603:47;22680:34;22675:2;22666:12;;22659:56;22746:3;22740;22731:13;;22724:26;22785:16;;;22781:25;;22775:3;22766:13;;22759:48;22832:3;22823:13;;22816:25;22876:16;;;22872:25;22866:3;22857:13;;22850:48;21531:3;22953;22944:13;;21519:16;-1:-1:-1;21551:11:1;;;22914:44;21454:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"leafIndex","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"destinationAndNonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"tips","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Dispatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"ImproperAttestation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updaterManager","type":"address"}],"name":"NewUpdaterManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"address","name":"reporter","type":"address"}],"name":"UpdaterSlashed","type":"event"},{"inputs":[],"name":"MAX_MESSAGE_BODY_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipientAddress","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"improperAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUpdaterManager","name":"_updaterManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterManager","type":"address"}],"name":"setUpdaterManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Home.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"suggestUpdate","outputs":[{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updaterManager","outputs":[{"internalType":"contract IUpdaterManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"notice":"Emitted when a new message is dispatched via Nomad"},"ImproperAttestation(address,bytes)":{"notice":"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state"},"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"NewUpdaterManager(address)":{"notice":"Emitted when the UpdaterManager contract is changed"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"},"UpdaterSlashed(address,address)":{"notice":"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)"}},"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"notice":"Dispatch the message to the destination domain \u0026 recipient"},"improperAttestation(bytes)":{"notice":"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation."},"root()":{"notice":"Calculates and returns tree's current root"},"setUpdater(address)":{"notice":"Set a new Updater"},"setUpdaterManager(address)":{"notice":"Set a new UpdaterManager contract"},"suggestUpdate()":{"notice":"Suggest an update for the Updater to sign and submit."}},"version":1},"developerDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"params":{"destinationAndNonce":"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)","leafIndex":"Index of message's leaf in merkle tree","message":"Raw bytes of message","messageHash":"Hash of message; the leaf inserted to the Merkle tree for the message","tips":"Tips paid for the remote off-chain agents"}},"ImproperAttestation(address,bytes)":{"params":{"attestation":"Attestation data and signature","updater":"Updater who signed improper attestation"}},"NewUpdaterManager(address)":{"params":{"updaterManager":"The address of the new updaterManager"}},"UpdaterSlashed(address,address)":{"params":{"reporter":"The address of the entity that reported the updater misbehavior","updater":"The address of the updater"}}},"kind":"dev","methods":{"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"details":"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.","params":{"_destinationDomain":"Domain of destination chain","_messageBody":"Raw bytes content of message","_recipientAddress":"Address of recipient on destination chain as bytes32"}},"improperAttestation(bytes)":{"details":"Reverts (and doesn't slash updater) if signature is invalid or update not current","params":{"_attestation":"Attestation data and signature"},"returns":{"_0":"TRUE if update was an Improper Attestation (implying Updater was slashed)"}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setUpdater(address)":{"details":"To be set when rotating Updater after Fraud","params":{"_updater":"the new Updater"}},"setUpdaterManager(address)":{"details":"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation","params":{"_updaterManager":"the new UpdaterManager contract"}},"suggestUpdate()":{"details":"If no messages have been sent, null bytes returned for both","returns":{"_nonce":"Current nonce","_root":"Current merkle root"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum Home.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"params\":{\"destinationAndNonce\":\"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\",\"leafIndex\":\"Index of message's leaf in merkle tree\",\"message\":\"Raw bytes of message\",\"messageHash\":\"Hash of message; the leaf inserted to the Merkle tree for the message\",\"tips\":\"Tips paid for the remote off-chain agents\"}},\"ImproperAttestation(address,bytes)\":{\"params\":{\"attestation\":\"Attestation data and signature\",\"updater\":\"Updater who signed improper attestation\"}},\"NewUpdaterManager(address)\":{\"params\":{\"updaterManager\":\"The address of the new updaterManager\"}},\"UpdaterSlashed(address,address)\":{\"params\":{\"reporter\":\"The address of the entity that reported the updater misbehavior\",\"updater\":\"The address of the updater\"}}},\"kind\":\"dev\",\"methods\":{\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"details\":\"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.\",\"params\":{\"_destinationDomain\":\"Domain of destination chain\",\"_messageBody\":\"Raw bytes content of message\",\"_recipientAddress\":\"Address of recipient on destination chain as bytes32\"}},\"improperAttestation(bytes)\":{\"details\":\"Reverts (and doesn't slash updater) if signature is invalid or update not current\",\"params\":{\"_attestation\":\"Attestation data and signature\"},\"returns\":{\"_0\":\"TRUE if update was an Improper Attestation (implying Updater was slashed)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setUpdater(address)\":{\"details\":\"To be set when rotating Updater after Fraud\",\"params\":{\"_updater\":\"the new Updater\"}},\"setUpdaterManager(address)\":{\"details\":\"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\",\"params\":{\"_updaterManager\":\"the new UpdaterManager contract\"}},\"suggestUpdate()\":{\"details\":\"If no messages have been sent, null bytes returned for both\",\"returns\":{\"_nonce\":\"Current nonce\",\"_root\":\"Current merkle root\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"notice\":\"Emitted when a new message is dispatched via Nomad\"},\"ImproperAttestation(address,bytes)\":{\"notice\":\"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state\"},\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"NewUpdaterManager(address)\":{\"notice\":\"Emitted when the UpdaterManager contract is changed\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"},\"UpdaterSlashed(address,address)\":{\"notice\":\"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)\"}},\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Dispatch the message to the destination domain \u0026 recipient\"},\"improperAttestation(bytes)\":{\"notice\":\"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation.\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"},\"setUpdater(address)\":{\"notice\":\"Set a new Updater\"},\"setUpdaterManager(address)\":{\"notice\":\"Set a new UpdaterManager contract\"},\"suggestUpdate()\":{\"notice\":\"Suggest an update for the Updater to sign and submit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Home\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"MAX_MESSAGE_BODY_BYTES()":"522ae002","VERSION()":"ffa1ad74","count()":"06661abd","dispatch(uint32,bytes32,uint32,bytes,bytes)":"f7560e40","historicalRoots(uint256)":"7ea97f40","improperAttestation(bytes)":"0afe7f90","initialize(address)":"c4d66de8","localDomain()":"8d3638f4","nonce()":"affed0e0","owner()":"8da5cb5b","renounceOwnership()":"715018a6","root()":"ebf0c717","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","setUpdaterManager(address)":"9776120e","state()":"c19d93fb","suggestUpdate()":"36e104de","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","tree()":"fd54b228","updater()":"df034cd0","updaterManager()":"9df6c8e1"}},"solidity/UpdaterManager.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/UpdaterManager.sol:IUpdaterManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"address payable","name":"_reporter","type":"address"}],"name":"slashUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"IUpdaterManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"slashUpdater(address)":"5b3c2cbf","updater()":"df034cd0"}},"solidity/UpdaterManager.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122053b404cb801ab494745e26639a91af69ae049f0725ba055f234476db3559a1e264736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122053b404cb801ab494745e26639a91af69ae049f0725ba055f234476db3559a1e264736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"80646:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;80646:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"80646:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:MerkleTreeManager":{"code":"0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212201a04f9fd6ec545477fca6f1cb2ff2a3834f1eb10850e7a9fc0772460433bada964736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212201a04f9fd6ec545477fca6f1cb2ff2a3834f1eb10850e7a9fc0772460433bada964736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"95896:968:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"95896:968:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96501:81;96565:10;;96501:81;;;160:25:1;;;148:2;133:18;96501:81:0;;;;;;;96045:32;;;;;;:::i;:::-;;:::i;96317:81::-;;;:::i;96013:26::-;;;;;;;96045:32;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;96045:32:0;:::o;96317:81::-;96354:7;96380:11;:4;:9;:11::i;:::-;96373:18;;96317:81;:::o;82785:122::-;82842:7;82868:32;82880:5;82887:12;:10;:12::i;:::-;82868:11;:32::i;:::-;82861:39;82785:122;-1:-1:-1;;82785:122:0:o;83025:964::-;83070:34;;:::i;:::-;83129:3;83116:16;;83155:3;83116:10;83142;;:16;83181:3;83168:10;;;:16;83207:3;83194:10;;;:16;83233:3;83220:10;;;:16;83259:3;83246:10;;;:16;83285:3;83272:10;;;:16;83311:3;83298:10;;;:16;83337:3;83324:10;;;:16;83363:3;83350:10;;;:16;83390:4;83376:11;;;:18;83418:4;83404:11;;;:18;83446:4;83432:11;;;:18;83474:4;83460:11;;;:18;83502:4;83488:11;;;:18;83530:4;83516:11;;;:18;83558:4;83544:11;;;:18;83586:4;83572:11;;;:18;83614:4;83600:11;;;:18;83642:4;83628:11;;;:18;83670:4;83656:11;;;:18;83698:4;83684:11;;;:18;83726:4;83712:11;;;:18;83754:4;83740:11;;;:18;83782:4;83768:11;;;:18;83810:4;83796:11;;;:18;83838:4;83824:11;;;:18;83866:4;83852:11;;;:18;83894:4;83880:11;;;:18;83922:4;83908:11;;;:18;83950:4;83936:11;;;:18;83978:4;83964:11;;;:18;83116:7;83025:964::o;82129:589::-;82302:11;;;;82253:16;;;82324:388;80709:2;82344:1;:14;82324:388;;;82410:4;82395:11;;;82394:20;;;82432:12;;;82428:215;;82502:5;82515:1;82502:15;;;;;;;:::i;:::-;;;82485:43;;;;;;909:19:1;;;;944:12;;937:28;;;981:12;;82485:43:0;;;;;;;;;;;;82475:54;;;;;;82464:65;;82428:215;;;82606:8;82616:7;82624:1;82616:10;;;;;;;:::i;:::-;;;;;82589:38;;;;;;;;909:19:1;;;953:2;944:12;;937:28;990:2;981:12;;752:247;82589:38:0;;;;;;;;;;;;;82579:49;;;;;;82568:60;;82428:215;-1:-1:-1;82684:3:0;;82324:388;;;;82275:443;82129:589;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;563:184::-;615:77;612:1;605:88;712:4;709:1;702:15;736:4;733:1;726:15","abiDefinition":[{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"root()":{"notice":"Calculates and returns tree's current root"}},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"MerkleTreeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"count()":"06661abd","historicalRoots(uint256)":"7ea97f40","root()":"ebf0c717","tree()":"fd54b228"}},"solidity/UpdaterManager.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205b0426a88e5a1b0384a5cea98fed44120bb489adf91d82da5fd0332744f1bb1b64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205b0426a88e5a1b0384a5cea98fed44120bb489adf91d82da5fd0332744f1bb1b64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"34355:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;34355:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"34355:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Ownable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"constructor":{"details":"Initializes the contract setting the deployer as the initial owner."},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Ownable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/UpdaterManager.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/UpdaterManager.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220840fba12deb870891a7dbc39187831add8b9804cf51a0dc6ac467b0de430082764736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220840fba12deb870891a7dbc39187831add8b9804cf51a0dc6ac467b0de430082764736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"42725:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;42725:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"42725:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209c5fc3e05f7a2411166d6f55c87041b3eb88f0998e4837a2f524f3835902bfdd64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209c5fc3e05f7a2411166d6f55c87041b3eb88f0998e4837a2f524f3835902bfdd64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"91667:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;91667:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"91667:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ebad72f7fd3317d85bf44c4b7a1658c6190a1b86b3e21188aaa637c95d1113b564736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220ebad72f7fd3317d85bf44c4b7a1658c6190a1b86b3e21188aaa637c95d1113b564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"88666:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;88666:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"88666:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220942898ca74b9cab7df55dc078162794c91fd26295ea1119c0f3e854102564e6e64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220942898ca74b9cab7df55dc078162794c91fd26295ea1119c0f3e854102564e6e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"33243:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;33243:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"33243:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220883677a140a1c4dac75b336e45f111be9dbba3c78a5791534cd010e3455215ca64736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220883677a140a1c4dac75b336e45f111be9dbba3c78a5791534cd010e3455215ca64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"995:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;995:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"995:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;3508:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;3508:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/UpdaterManager.sol:UpdaterManager":{"code":"0x60806040526040516108a83803806108a8833981016040819052610022916100a0565b61002b33610050565b600280546001600160a01b0319166001600160a01b03929092169190911790556100d0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100b257600080fd5b81516001600160a01b03811681146100c957600080fd5b9392505050565b6107c9806100df6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80639d54f4191161005b5780639d54f419146101005780639fa92f9d14610113578063df034cd014610133578063f2fde38b1461015157600080fd5b80635b3c2cbf1461008d5780636ef0f37f146100a2578063715018a6146100b55780638da5cb5b146100bd575b600080fd5b6100a061009b36600461076f565b610164565b005b6100a06100b036600461076f565b610237565b6100a06103a9565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100a061010e36600461076f565b61042c565b6001546100d79073ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff166100d7565b6100a061015f36600461076f565b6105a8565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f21686f6d6500000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60405173ffffffffffffffffffffffffffffffffffffffff821681527f4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81163b610336576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f21636f6e747261637420686f6d6500000000000000000000000000000000000060448201526064016101e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de219060200161022c565b60005473ffffffffffffffffffffffffffffffffffffffff16331461042a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556001546040517f9d54f419000000000000000000000000000000000000000000000000000000008152600481019290925290911690639d54f41990602401600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681527f9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c329250602001905061022c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81166106cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101e1565b6106d5816106d8565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106d557600080fd5b60006020828403121561078157600080fd5b813561078c8161074d565b939250505056fea2646970667358221220cae6d97d734603030c73ce13d0eac208b8db318b2417b12187666996b512ee8e64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100885760003560e01c80639d54f4191161005b5780639d54f419146101005780639fa92f9d14610113578063df034cd014610133578063f2fde38b1461015157600080fd5b80635b3c2cbf1461008d5780636ef0f37f146100a2578063715018a6146100b55780638da5cb5b146100bd575b600080fd5b6100a061009b36600461076f565b610164565b005b6100a06100b036600461076f565b610237565b6100a06103a9565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100a061010e36600461076f565b61042c565b6001546100d79073ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff166100d7565b6100a061015f36600461076f565b6105a8565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f21686f6d6500000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60405173ffffffffffffffffffffffffffffffffffffffff821681527f4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81163b610336576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f21636f6e747261637420686f6d6500000000000000000000000000000000000060448201526064016101e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de219060200161022c565b60005473ffffffffffffffffffffffffffffffffffffffff16331461042a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556001546040517f9d54f419000000000000000000000000000000000000000000000000000000008152600481019290925290911690639d54f41990602401600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681527f9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c329250602001905061022c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81166106cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101e1565b6106d5816106d8565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106d557600080fd5b60006020828403121561078157600080fd5b813561078c8161074d565b939250505056fea2646970667358221220cae6d97d734603030c73ce13d0eac208b8db318b2417b12187666996b512ee8e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"120420:2751:0:-:0;;;121439:98;;;;;;;;;;;;;;;;;;:::i;:::-;118596:32;118188:10;118596:18;:32::i;:::-;121504:8:::1;:26:::0;;-1:-1:-1;;;;;;121504:26:0::1;-1:-1:-1::0;;;;;121504:26:0;;;::::1;::::0;;;::::1;::::0;;120420:2751;;119945:187;120018:16;120037:6;;-1:-1:-1;;;;;120053:17:0;;;-1:-1:-1;;;;;;120053:17:0;;;;;;120085:40;;120037:6;;;;;;;120085:40;;120018:16;120085:40;120008:124;119945:187;:::o;14:290:1:-;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;179:16;;-1:-1:-1;;;;;224:31:1;;214:42;;204:70;;270:1;267;260:12;204:70;293:5;14:290;-1:-1:-1;;;14:290:1:o;:::-;120420:2751:0;;;;;;","srcMapRuntime":"120420:2751:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;122590:120;;;;;;:::i;:::-;;:::i;:::-;;121770:172;;;;;;:::i;:::-;;:::i;123085:84::-;;;:::i;118711:85::-;118757:7;118783:6;;;118711:85;;;885:42:1;873:55;;;855:74;;843:2;828:18;118711:85:0;;;;;;;122116:197;;;;;;:::i;:::-;;:::i;120559:19::-;;;;;;;;;122813:92;122890:8;;;;122813:92;;119593:198;;;;;;:::i;:::-;;:::i;122590:120::-;121355:4;;;;121341:10;:18;121333:36;;;;;;;1142:2:1;121333:36:0;;;1124:21:1;1181:1;1161:18;;;1154:29;1219:7;1199:18;;;1192:35;1244:18;;121333:36:0;;;;;;;;;122681:22:::1;::::0;885:42:1;873:55;;855:74;;122681:22:0::1;::::0;843:2:1;828:18;122681:22:0::1;;;;;;;;122590:120:::0;:::o;121770:172::-;118757:7;118783:6;118923:23;118783:6;118188:10;118923:23;118915:68;;;;;;;1714:2:1;118915:68:0;;;1696:21:1;;;1733:18;;;1726:30;1792:34;1772:18;;;1765:62;1844:18;;118915:68:0;1512:356:1;118915:68:0;98137:19;;;;121831:52:::1;;;::::0;::::1;::::0;;2075:2:1;121831:52:0::1;::::0;::::1;2057:21:1::0;2114:2;2094:18;;;2087:30;2153:16;2133:18;;;2126:44;2187:18;;121831:52:0::1;1873:338:1::0;121831:52:0::1;121893:4;:12:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;121921:14:::1;::::0;855:74:1;;;121921:14:0::1;::::0;843:2:1;828:18;121921:14:0::1;709:226:1::0;123085:84:0;118757:7;118783:6;118923:23;118783:6;118188:10;118923:23;118915:68;;;;;;;1714:2:1;118915:68:0;;;1696:21:1;;;1733:18;;;1726:30;1792:34;1772:18;;;1765:62;1844:18;;118915:68:0;1512:356:1;118915:68:0;123085:84::o;122116:197::-;118757:7;118783:6;118923:23;118783:6;118188:10;118923:23;118915:68;;;;;;;1714:2:1;118915:68:0;;;1696:21:1;;;1733:18;;;1726:30;1792:34;1772:18;;;1765:62;1844:18;;118915:68:0;1512:356:1;118915:68:0;122190:8:::1;:26:::0;;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;122231:4:0;122226:38:::1;::::0;;;;::::1;::::0;::::1;855:74:1::0;;;;122231:4:0;;::::1;::::0;122226:21:::1;::::0;828:18:1;;122226:38:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;122279:27:0::1;::::0;885:42:1;873:55;;855:74;;122279:27:0::1;::::0;-1:-1:-1;843:2:1;828:18;;-1:-1:-1;122279:27:0::1;709:226:1::0;119593:198:0;118757:7;118783:6;118923:23;118783:6;118188:10;118923:23;118915:68;;;;;;;1714:2:1;118915:68:0;;;1696:21:1;;;1733:18;;;1726:30;1792:34;1772:18;;;1765:62;1844:18;;118915:68:0;1512:356:1;118915:68:0;119681:22:::1;::::0;::::1;119673:73;;;::::0;::::1;::::0;;2418:2:1;119673:73:0::1;::::0;::::1;2400:21:1::0;2457:2;2437:18;;;2430:30;2496:34;2476:18;;;2469:62;2567:8;2547:18;;;2540:36;2593:19;;119673:73:0::1;2216:402:1::0;119673:73:0::1;119756:28;119775:8;119756:18;:28::i;:::-;119593:198:::0;:::o;119945:187::-;120018:16;120037:6;;;120053:17;;;;;;;;;;120085:40;;120037:6;;;;;;;120085:40;;120018:16;120085:40;120008:124;119945:187;:::o;14:162:1:-;108:42;101:5;97:54;90:5;87:65;77:93;;166:1;163;156:12;181:263;248:6;301:2;289:9;280:7;276:23;272:32;269:52;;;317:1;314;307:12;269:52;356:9;343:23;375:39;408:5;375:39;:::i;:::-;433:5;181:263;-1:-1:-1;;;181:263:1:o","abiDefinition":[{"inputs":[{"internalType":"address","name":"_updaterAddress","type":"address"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"reporter","type":"address"}],"name":"FakeSlashed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"home","type":"address"}],"name":"NewHome","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"home","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_home","type":"address"}],"name":"setHome","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterAddress","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_reporter","type":"address"}],"name":"slashUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"FakeSlashed(address)":{"notice":"Emitted when slashUpdater is called"},"NewHome(address)":{"notice":"Emitted when a new home is set"},"NewUpdater(address)":{"notice":"Emitted when a new updater is set"}},"kind":"user","methods":{"setHome(address)":{"notice":"Set the address of the a new home contract"},"setUpdater(address)":{"notice":"Set the address of a new updater"},"slashUpdater(address)":{"notice":"Slashes the updater"},"updater()":{"notice":"Get address of current updater"}},"notice":"MVP / centralized version of contract that will manage Updater bonding, slashing, selection and rotation","version":1},"developerDoc":{"author":"Illusory Systems Inc.","events":{"NewHome(address)":{"params":{"home":"The address of the new home contract"}},"NewUpdater(address)":{"params":{"updater":"The address of the new updater"}}},"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin Ownable implementation of renounceOwnership to make it a no-op"},"setHome(address)":{"details":"only callable by trusted owner","params":{"_home":"The address of the new home contract"}},"setUpdater(address)":{"details":"only callable by trusted owner","params":{"_updaterAddress":"The address of the new updater"}},"slashUpdater(address)":{"details":"Currently does nothing, functionality will be implemented later when updater bonding and rotation are also implemented","params":{"_reporter":"The address of the entity that reported the updater fraud"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."},"updater()":{"returns":{"_0":"the updater address"}}},"title":"UpdaterManager","version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterAddress\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"FakeSlashed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"home\",\"type\":\"address\"}],\"name\":\"NewHome\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"home\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_home\",\"type\":\"address\"}],\"name\":\"setHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterAddress\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Illusory Systems Inc.\",\"events\":{\"NewHome(address)\":{\"params\":{\"home\":\"The address of the new home contract\"}},\"NewUpdater(address)\":{\"params\":{\"updater\":\"The address of the new updater\"}}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin Ownable implementation of renounceOwnership to make it a no-op\"},\"setHome(address)\":{\"details\":\"only callable by trusted owner\",\"params\":{\"_home\":\"The address of the new home contract\"}},\"setUpdater(address)\":{\"details\":\"only callable by trusted owner\",\"params\":{\"_updaterAddress\":\"The address of the new updater\"}},\"slashUpdater(address)\":{\"details\":\"Currently does nothing, functionality will be implemented later when updater bonding and rotation are also implemented\",\"params\":{\"_reporter\":\"The address of the entity that reported the updater fraud\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"updater()\":{\"returns\":{\"_0\":\"the updater address\"}}},\"title\":\"UpdaterManager\",\"version\":1},\"userdoc\":{\"events\":{\"FakeSlashed(address)\":{\"notice\":\"Emitted when slashUpdater is called\"},\"NewHome(address)\":{\"notice\":\"Emitted when a new home is set\"},\"NewUpdater(address)\":{\"notice\":\"Emitted when a new updater is set\"}},\"kind\":\"user\",\"methods\":{\"setHome(address)\":{\"notice\":\"Set the address of the a new home contract\"},\"setUpdater(address)\":{\"notice\":\"Set the address of a new updater\"},\"slashUpdater(address)\":{\"notice\":\"Slashes the updater\"},\"updater()\":{\"notice\":\"Get address of current updater\"}},\"notice\":\"MVP / centralized version of contract that will manage Updater bonding, slashing, selection and rotation\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"UpdaterManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"home()":"9fa92f9d","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setHome(address)":"6ef0f37f","setUpdater(address)":"9d54f419","slashUpdater(address)":"5b3c2cbf","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/UpdaterManager.sol:UpdaterStorage":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldUpdater","type":"address"},{"indexed":false,"internalType":"address","name":"newUpdater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"homeDomain","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"nonce","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"}],"name":"Update","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"NewUpdater(address,address)":{"notice":"Emitted when Updater is rotated"},"Update(uint32,uint32,bytes32,bytes)":{"notice":"Emitted when update is made on Home or unconfirmed update root is submitted on Replica"}},"kind":"user","methods":{},"version":1},"developerDoc":{"events":{"NewUpdater(address,address)":{"params":{"newUpdater":"The address of the new updater","oldUpdater":"The address of the old updater"}},"Update(uint32,uint32,bytes32,bytes)":{"params":{"homeDomain":"Domain of home contract","nonce":"Nonce of new merkle root","root":"New merkle root","signature":"Updater's signature on `homeDomain`, `nonce` and `root`"}}},"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldUpdater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newUpdater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"homeDomain\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"nonce\",\"type\":\"uint32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Update\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"params\":{\"newUpdater\":\"The address of the new updater\",\"oldUpdater\":\"The address of the old updater\"}},\"Update(uint32,uint32,bytes32,bytes)\":{\"params\":{\"homeDomain\":\"Domain of home contract\",\"nonce\":\"Nonce of new merkle root\",\"root\":\"New merkle root\",\"signature\":\"Updater's signature on `homeDomain`, `nonce` and `root`\"}}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"NewUpdater(address,address)\":{\"notice\":\"Emitted when Updater is rotated\"},\"Update(uint32,uint32,bytes32,bytes)\":{\"notice\":\"Emitted when update is made on Home or unconfirmed update root is submitted on Replica\"}},\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"UpdaterStorage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/UpdaterManager.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220147957fda2ff464ad00468048258af6268e10639ff3cebac8e6d8f510d6c982d64736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea2646970667358221220147957fda2ff464ad00468048258af6268e10639ff3cebac8e6d8f510d6c982d64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract UpdaterStorage is Initializable, OwnableUpgradeable {\n // ============ Immutable Variables ============\n\n // Domain of chain on which the contract is deployed\n uint32 public immutable localDomain;\n\n // ============ Public Variables ============\n\n // Address of bonded Updater\n address public updater;\n\n ISystemMessenger public systemMessenger;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when update is made on Home\n * or unconfirmed update root is submitted on Replica\n * @param homeDomain Domain of home contract\n * @param nonce Nonce of new merkle root\n * @param root New merkle root\n * @param signature Updater's signature on `homeDomain`, `nonce` and `root`\n */\n // TODO: emit abi encoded update instead?\n event Update(\n uint32 indexed homeDomain,\n uint32 indexed nonce,\n bytes32 indexed root,\n bytes signature\n );\n\n /**\n * @notice Emitted when Updater is rotated\n * @param oldUpdater The address of the old updater\n * @param newUpdater The address of the new updater\n */\n event NewUpdater(address oldUpdater, address newUpdater);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n // ============ Initializer ============\n\n function __SynapseBase_initialize(address _updater) internal onlyInitializing {\n __Ownable_init();\n _setUpdater(_updater);\n }\n\n // ============ Modifiers ============\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n // ============ Restricted Functions ============\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n // ============ Internal Functions ============\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n\n /**\n * @notice Set the Updater\n * @param _newUpdater Address of the new Updater\n */\n function _setUpdater(address _newUpdater) internal {\n address _oldUpdater = updater;\n updater = _newUpdater;\n emit NewUpdater(_oldUpdater, _newUpdater);\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AuthManager {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ LIBRARIES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint256[50] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized updater.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Updater that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkUpdaterAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isUpdater(_view.attestationDomain(), _updater), \"Signer is not an updater\");\n }\n\n function _checkWatchtowerAuth(bytes memory _report)\n internal\n view\n returns (address _watchtower, bytes29 _data)\n {\n // TODO: check if _report is valid, once watchtower message standard is finalized\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIRTUAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _isUpdater(uint32 _homeDomain, address _updater) internal view virtual returns (bool);\n\n function _isWatchtower(address _watchtower) internal view virtual returns (bool);\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, UpdaterStorage, AuthManager {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain) UpdaterStorage(_localDomain) {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n // initialize queue, set Updater Manager, and initialize\n _setUpdaterManager(_updaterManager);\n __SynapseBase_initialize(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n _setUpdater(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _updater, bytes29 _view) = _checkUpdaterAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail();\n emit ImproperAttestation(_updater, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail() internal {\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(updater, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n function _isUpdater(uint32 _homeDomain, address _updater)\n internal\n view\n override\n returns (bool)\n {\n require(_homeDomain == localDomain, \"Wrong domain\");\n return _updater == updater;\n }\n\n function _isWatchtower(address) internal pure override returns (bool) {\n return false;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"177:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"177:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;201:33;;233:1;201:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;201:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x071457bb27141797092b4996c821282db39937d8f9d71c62c07f756084100cbf\",\"urls\":[\"bzz-raw://21e1c4b136e52aef75f3ff348e1d81d10110027655fdb4b8344b86527f482544\",\"dweb:/ipfs/QmUDoocy4fKEuhGHyZG1Lb8U7TVKjZbmByPFzibtX9LbwU\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file +{"solidity/UpdaterManager.sol:AbstractGuardRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"AbstractGuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:AbstractNotaryRegistry":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"AbstractNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Address":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220173016a61f21743599903dd0d6ddd5b3dad05e450eb61cbfa1bef7e9cdd1125464736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220173016a61f21743599903dd0d6ddd5b3dad05e450eb61cbfa1bef7e9cdd1125464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"117245:8061:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;117245:8061:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"117245:8061:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Address\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:AddressUpgradeable":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209038b5275e330d7536c3011fb042d43a4368babfc61b637ed01282db0eca282064736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209038b5275e330d7536c3011fb042d43a4368babfc61b637ed01282db0eca282064736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"94698:7122:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;94698:7122:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"94698:7122:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Collection of functions related to the address type","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Collection of functions related to the address type\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"AddressUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Attestation":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e6638e47bbfe98a03f10367fbd38f861cb726bb09d0bdf010a2d30ed59e4606164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e6638e47bbfe98a03f10367fbd38f861cb726bb09d0bdf010a2d30ed59e4606164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"32483:3216:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;32483:3216:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"32483:3216:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_HOME_DOMAIN":{"details":"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_HOME_DOMAIN\":{\"details\":\"AttestationData memory layout [000 .. 004): homeDomain uint32 4 bytes [004 .. 008): nonce uint32 4 bytes [008 .. 040): root bytes32 32 bytes Attestation memory layout [000 .. 040): data bytes 40 bytes (see above) [040 .. END): signature bytes ?? bytes (64/65 bytes)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Attestation\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Auth":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220faf9cb1a2958413aaa5f5fe79b9603a2e97dd08c57fc9629a8493be25225d5b864736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220faf9cb1a2958413aaa5f5fe79b9603a2e97dd08c57fc9629a8493be25225d5b864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"46606:610:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;46606:610:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"46606:610:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Auth\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Context":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Context\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:ContextUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.","kind":"dev","methods":{},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"details\":\"Provides information about the current execution context, including the sender of the transaction and its data. While these are generally available via msg.sender and msg.data, they should not be accessed in such a direct manner, since when dealing with meta-transactions the account sending and paying for execution may not be the actual sender (as far as an application is concerned). This contract is only required for intermediate, library-like contracts.\",\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"ContextUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:DomainNotaryRegistry":{"code":"0x60a060405234801561001057600080fd5b506040516102e73803806102e783398101604081905261002f9161003d565b63ffffffff1660805261006a565b60006020828403121561004f57600080fd5b815163ffffffff8116811461006357600080fd5b9392505050565b608051610265610082600039600050506102656000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207ef2ba07bd558db2e2e06e92ae876a511cef227a7494199035e127c36887c73864736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c80638e62e9ef146100465780639817e31514610061578063c07dc7f514610076575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b6100696100bf565b604051610058919061018d565b6100896100843660046101e7565b6100cb565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b60006100ba60006100dd565b905090565b60606100ba60006100e7565b60006100d781836100fb565b92915050565b60006100d7825490565b606060006100f483610107565b9392505050565b60006100f48383610163565b60608160000180548060200260200160405190810160405280929190818152602001828054801561015757602002820191906000526020600020905b815481526020019060010190808311610143575b50505050509050919050565b600082600001828154811061017a5761017a610200565b9060005260206000200154905092915050565b6020808252825182820181905260009190848201906040850190845b818110156101db57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101a9565b50909695505050505050565b6000602082840312156101f957600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212207ef2ba07bd558db2e2e06e92ae876a511cef227a7494199035e127c36887c73864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"59708:5230:0:-:0;;;62797:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62842:30;;;;59708:5230;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;59708:5230:0;;;;;;;;;;;","srcMapRuntime":"59708:5230:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63652:99;;;:::i;:::-;;;160:25:1;;;148:2;133:18;63652:99:0;;;;;;;;63425:105;;;:::i;:::-;;;;;;;:::i;63536:110::-;;;;;;:::i;:::-;;:::i;:::-;;;1243:42:1;1231:55;;;1213:74;;1201:2;1186:18;63536:110:0;1067:226:1;63652:99:0;63701:7;63727:17;:8;:15;:17::i;:::-;63720:24;;63652:99;:::o;63425:105::-;63471:16;63506:17;:8;:15;:17::i;63536:110::-;63594:7;63620:19;63594:7;63632:6;63620:11;:19::i;:::-;63613:26;63536:110;-1:-1:-1;;63536:110:0:o;55939:115::-;56002:7;56028:19;56036:3;51554:18;;51472:107;57092:257;57155:16;57183:22;57208:19;57216:3;57208:7;:19::i;:::-;57183:44;57092:257;-1:-1:-1;;;57092:257:0:o;56396:156::-;56470:7;56520:22;56524:3;56536:5;56520:3;:22::i;52579:109::-;52635:16;52670:3;:11;;52663:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52579:109;;;:::o;51921:118::-;51988:7;52014:3;:11;;52026:5;52014:18;;;;;;;;:::i;:::-;;;;;;;;;52007:25;;51921:118;;;;:::o;196:681:1:-;367:2;419:21;;;489:13;;392:18;;;511:22;;;338:4;;367:2;590:15;;;;564:2;549:18;;;338:4;633:218;647:6;644:1;641:13;633:218;;;712:13;;727:42;708:62;696:75;;826:15;;;;791:12;;;;669:1;662:9;633:218;;;-1:-1:-1;868:3:1;;196:681;-1:-1:-1;;;;;;196:681:1:o;882:180::-;941:6;994:2;982:9;973:7;969:23;965:32;962:52;;;1010:1;1007;1000:12;962:52;-1:-1:-1;1033:23:1;;882:180;-1:-1:-1;882:180:1:o;1298:184::-;1350:77;1347:1;1340:88;1447:4;1444:1;1437:15;1471:4;1468:1;1461:15","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_trackedDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryRemoved","type":"event"},{"inputs":[],"name":"allNotaries","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNotary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notariesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_trackedDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"DomainNotaryRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"allNotaries()":"9817e315","getNotary(uint256)":"c07dc7f5","notariesAmount()":"8e62e9ef"}},"solidity/UpdaterManager.sol:ECDSA":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200d08df708f0e20acb05557a8bfb4fdaa5d834a3c76f47cf5ef5263ca0795947164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212200d08df708f0e20acb05557a8bfb4fdaa5d834a3c76f47cf5ef5263ca0795947164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"37680:8924:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;37680:8924:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"37680:8924:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"ECDSA\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:EnumerableSet":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212203ec4b2937303fd20eb43d43650d3288d4f4d8d01fbca0f6e933f10a1d93c030e64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212203ec4b2937303fd20eb43d43650d3288d4f4d8d01fbca0f6e933f10a1d93c030e64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"48338:11368:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;48338:11368:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"48338:11368:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"EnumerableSet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:GuardRegistry":{"code":"0x608060405234801561001057600080fd5b50610265806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212206f43888a818e9d4f992c4856f348d474f6697c6995f67db46b7bc57aa6c3098564736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063246c244914610046578063629ddf69146100615780639fe03fa214610099575b600080fd5b61004e6100ae565b6040519081526020015b60405180910390f35b61007461006f36600461018d565b6100bf565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610058565b6100a16100d1565b60405161005891906101a6565b60006100ba60006100dd565b905090565b60006100cb81836100e7565b92915050565b60606100ba60006100fa565b60006100cb825490565b60006100f38383610107565b9392505050565b606060006100f383610131565b600082600001828154811061011e5761011e610200565b9060005260206000200154905092915050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561018157602002820191906000526020600020905b81548152602001906001019080831161016d575b50505050509050919050565b60006020828403121561019f57600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b818110156101f457835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016101c2565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea26469706673582212206f43888a818e9d4f992c4856f348d474f6697c6995f67db46b7bc57aa6c3098564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"65288:3868:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"65288:3868:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67986:95;;;:::i;:::-;;;160:25:1;;;148:2;133:18;67986:95:0;;;;;;;;67873:107;;;;;;:::i;:::-;;:::i;:::-;;;557:42:1;545:55;;;527:74;;515:2;500:18;67873:107:0;381:226:1;67766:101:0;;;:::i;:::-;;;;;;;:::i;67986:95::-;68033:7;68059:15;:6;:13;:15::i;:::-;68052:22;;67986:95;:::o;67873:107::-;67930:7;67956:17;67930:7;67966:6;67956:9;:17::i;:::-;67949:24;67873:107;-1:-1:-1;;67873:107:0:o;67766:101::-;67810:16;67845:15;:6;:13;:15::i;55939:115::-;56002:7;56028:19;56036:3;51554:18;;51472:107;56396:156;56470:7;56520:22;56524:3;56536:5;56520:3;:22::i;:::-;56512:31;56396:156;-1:-1:-1;;;56396:156:0:o;57092:257::-;57155:16;57183:22;57208:19;57216:3;57208:7;:19::i;51921:118::-;51988:7;52014:3;:11;;52026:5;52014:18;;;;;;;;:::i;:::-;;;;;;;;;52007:25;;51921:118;;;;:::o;52579:109::-;52635:16;52670:3;:11;;52663:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52579:109;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;612:681::-;783:2;835:21;;;905:13;;808:18;;;927:22;;;754:4;;783:2;1006:15;;;;980:2;965:18;;;754:4;1049:218;1063:6;1060:1;1057:13;1049:218;;;1128:13;;1143:42;1124:62;1112:75;;1242:15;;;;1207:12;;;;1085:1;1078:9;1049:218;;;-1:-1:-1;1284:3:1;;612:681;-1:-1:-1;;;;;;612:681:1:o;1298:184::-;1350:77;1347:1;1340:88;1447:4;1444:1;1437:15;1471:4;1468:1;1461:15","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"GuardRegistry\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"allGuards()":"9fe03fa2","getGuard(uint256)":"629ddf69","guardsAmount()":"246c2449"}},"solidity/UpdaterManager.sol:Header":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122071475f0137e7fab40ea940971931a3cd0659ab8643a6c45696eed4d5b03c44dd64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122071475f0137e7fab40ea940971931a3cd0659ab8643a6c45696eed4d5b03c44dd64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"78294:3303:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;78294:3303:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"78294:3303:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_ORIGIN":{"details":"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_ORIGIN\":{\"details\":\"Header memory layout [000 .. 002): version uint16 2 bytes [002 .. 006): originDomain uint32 4 bytes [006 .. 038): sender bytes32 32 bytes [038 .. 042): nonce uint32 4 bytes [042 .. 046): destinationDomain uint32 4 bytes [046 .. 078): recipient bytes32 32 bytes [078 .. 082): optimisticSeconds uint32 4 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Header\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Home":{"code":"0x60c06040523480156200001157600080fd5b50604051620038c7380380620038c7833981016040819052620000349162000048565b63ffffffff16608081905260a05262000077565b6000602082840312156200005b57600080fd5b815163ffffffff811681146200007057600080fd5b9392505050565b60805160a051613823620000a460003960006118a70152600081816102ef0152610ea501526138236000f3fe6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea2646970667358221220ba13c1faec0e4c3a099925d7c203efd3f588ac7f865d7d75c54f5d2a2b204e3564736f6c634300080d0033","runtime-code":"0x6080604052600436106101ac5760003560e01c80639d54f419116100ec578063c4d66de81161008a578063f2fde38b11610064578063f2fde38b14610517578063f7560e4014610537578063fd54b2281461054a578063ffa1ad741461056157600080fd5b8063c4d66de8146104b5578063ccbdf9c9146104d5578063ebf0c7171461050257600080fd5b8063affed0e0116100c6578063affed0e014610413578063b7bc563e14610431578063c07dc7f514610451578063c19d93fb1461047157600080fd5b80639d54f419146103a85780639df6c8e1146103c85780639fe03fa2146103fe57600080fd5b8063715018a6116101595780638da5cb5b116101335780638da5cb5b146103265780638e62e9ef146103515780639776120e146103665780639817e3151461038657600080fd5b8063715018a6146102a65780637ea97f40146102bd5780638d3638f4146102dd57600080fd5b806336e104de1161018a57806336e104de1461021a578063522ae0021461024b578063629ddf691461026157600080fd5b806306661abd146101b15780630afe7f90146101d5578063246c244914610205575b600080fd5b3480156101bd57600080fd5b506020545b6040519081526020015b60405180910390f35b3480156101e157600080fd5b506101f56101f0366004613082565b610588565b60405190151581526020016101cc565b34801561021157600080fd5b506101c26106df565b34801561022657600080fd5b5061022f6106f0565b6040805163ffffffff90931683526020830191909152016101cc565b34801561025757600080fd5b506101c261080081565b34801561026d57600080fd5b5061028161027c3660046130b7565b610737565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cc565b3480156102b257600080fd5b506102bb61074a565b005b3480156102c957600080fd5b506101c26102d83660046130b7565b6107b3565b3480156102e957600080fd5b506103117f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101cc565b34801561033257600080fd5b5060855473ffffffffffffffffffffffffffffffffffffffff16610281565b34801561035d57600080fd5b506101c26107d4565b34801561037257600080fd5b506102bb6103813660046130f2565b6107e0565b34801561039257600080fd5b5061039b610853565b6040516101cc919061310f565b3480156103b457600080fd5b506102bb6103c33660046130f2565b61085f565b3480156103d457600080fd5b5061011e5461028190640100000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561040a57600080fd5b5061039b610920565b34801561041f57600080fd5b5061011e546103119063ffffffff1681565b34801561043d57600080fd5b506102bb61044c3660046130f2565b61092c565b34801561045d57600080fd5b5061028161046c3660046130b7565b6109da565b34801561047d57600080fd5b5061011e546104a8907801000000000000000000000000000000000000000000000000900460ff1681565b6040516101cc9190613198565b3480156104c157600080fd5b506102bb6104d03660046130f2565b6109e7565b3480156104e157600080fd5b5060b7546102819073ffffffffffffffffffffffffffffffffffffffff1681565b34801561050e57600080fd5b506101c2610bb1565b34801561052357600080fd5b506102bb6105323660046130f2565b610bbd565b6102bb6105453660046131ed565b610cb6565b34801561055657600080fd5b506020546101c29081565b34801561056d57600080fd5b50610576600081565b60405160ff90911681526020016101cc565b6000600261011e547801000000000000000000000000000000000000000000000000900460ff1660028111156105c0576105c0613169565b036106125760405162461bcd60e51b815260206004820152600c60248201527f6661696c6564207374617465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60008061061e84610fb0565b9150915060006106338262ffffff19166110c0565b9050600061064662ffffff1984166110d4565b60215490915063ffffffff8316101561068f5760218263ffffffff16815481106106725761067261327c565b9060005260206000200154810361068f5750600095945050505050565b610698846110e9565b7f287e2c0e041ca31a0ce7a1ed8b91a7425b2520880947cdbe778c457ca4c48e5b84876040516106c9929190613325565b60405180910390a160019450505050505b919050565b60006106eb60eb611201565b905090565b6021546000908190801561073257610709600182613383565b925060218363ffffffff16815481106107245761072461327c565b906000526020600020015491505b509091565b600061074460eb8361120b565b92915050565b60855473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b565b602181815481106107c357600080fd5b600091825260209091200154905081565b60006106eb60b8611201565b60855473ffffffffffffffffffffffffffffffffffffffff1633146108475760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b6108508161121e565b50565b60606106eb60b8611306565b61011e54640100000000900473ffffffffffffffffffffffffffffffffffffffff1633146108cf5760405162461bcd60e51b815260206004820152600f60248201527f21757064617465724d616e6167657200000000000000000000000000000000006044820152606401610609565b6108d881611313565b505061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff167801000000000000000000000000000000000000000000000000179055565b60606106eb60eb611306565b60855473ffffffffffffffffffffffffffffffffffffffff1633146109935760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b60b780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600061074460b88361120b565b60006109f36001611376565b90508015610a2857605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610a306114ca565b610a398261121e565b610ad361011e60049054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663df034cd06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace919061339a565b611313565b5061011e80547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000001790556021805460018101825560009182527f3a6357012c1a3ae0a17d304c9920310382d968ebcc4b1771f41c6b304205b57001558015610bad57605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006106eb600061154f565b60855473ffffffffffffffffffffffffffffffffffffffff163314610c245760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610609565b73ffffffffffffffffffffffffffffffffffffffff8116610cad5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610609565b61085081611562565b600261011e547801000000000000000000000000000000000000000000000000900460ff166002811115610cec57610cec613169565b03610d395760405162461bcd60e51b815260206004820152600c60248201527f6661696c656420737461746500000000000000000000000000000000000000006044820152606401610609565b61080081511115610d8c5760405162461bcd60e51b815260206004820152600c60248201527f6d736720746f6f206c6f6e6700000000000000000000000000000000000000006044820152606401610609565b34610da4610d99846115d9565b62ffffff19166115e6565b6bffffffffffffffffffffffff1614610dff5760405162461bcd60e51b815260206004820152600560248201527f21746970730000000000000000000000000000000000000000000000000000006044820152606401610609565b61011e54610e149063ffffffff1660016133b7565b61011e80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790556000610e5585611648565b61011e54604080517e0100000000000000000000000000000000000000000000000000000000000060208201527fffffffff000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060e090811b821660228401526026830186905293841b811660468301528a841b8116604a830152604e82018a90529288901b909216606e83015280518083036052018152607290920190529091506000610f1f8286866116a7565b80516020820120909150610f3281611721565b61011e5463ffffffff1660208a901b67ffffffff00000000161767ffffffffffffffff166001610f6160205490565b610f6b9190613383565b827f718e547b45036b0526c0cd2f2e3de248b0e8c042c714ecfbee3f5811a5e6e7858986604051610f9d9291906133df565b60405180910390a4505050505050505050565b600080610fbd8382611751565b905060286bffffffffffffffffffffffff601883901c16116110215760405162461bcd60e51b815260206004820152601260248201527f4e6f7420616e206174746573746174696f6e00000000000000000000000000006044820152606401610609565b61105561103362ffffff198316611775565b61105061104562ffffff19851661178a565b62ffffff19166117bd565b611810565b915061106f61106962ffffff19831661188f565b836118a3565b6110bb5760405162461bcd60e51b815260206004820152601660248201527f5369676e6572206973206e6f742061206e6f74617279000000000000000000006044820152606401610609565b915091565b600061074462ffffff19831660048061192b565b600061074462ffffff1983166008602061195b565b61011e805478020000000000000000000000000000000000000000000000007fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff90911617908190556040517f5b3c2cbf00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff6401000000009092049190911690635b3c2cbf90602401600060405180830381600087803b1580156111a357600080fd5b505af11580156111b7573d6000803e3d6000fd5b505060405133925073ffffffffffffffffffffffffffffffffffffffff841691507f98064af315f26d7333ba107ba43a128ec74345f4d4e6f2549840fe092a1c8bce90600090a350565b6000610744825490565b60006112178383611b19565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81163b6112825760405162461bcd60e51b815260206004820152601860248201527f21636f6e747261637420757064617465724d616e6167657200000000000000006044820152606401610609565b61011e80547fffffffffffffffff0000000000000000000000000000000000000000ffffffff1664010000000073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527f958d788fb4c373604cd4c73aa8c592de127d0819b49bb4dc02c8ecd666e965bf9060200160405180910390a150565b6060600061121783611b43565b600061132060b883611b9f565b905080156106da5760405173ffffffffffffffffffffffffffffffffffffffff831681527f7ed5310d8818d06ea4a196771a39a73bf55c815addbf7a52ba87c9be409c3dd19060200160405180910390a1919050565b605254600090610100900460ff1615611415578160ff16600114801561139b5750303b155b61140d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b506000919050565b60525460ff8084169116106114925760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610609565b50605280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff92909216919091179055600190565b605254610100900460ff166115475760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b1611bc1565b60006107448261155d611c47565b612108565b6085805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610744826002611751565b6000816115fc60025b62ffffff198316906121cb565b50611606836122cc565b61160f846122fa565b6116188561231b565b6116218661233c565b61162b9190613404565b6116359190613404565b61163f9190613404565b91505b50919050565b60007fffffffffffffffffffffffff00000000000000000000000000000000000000008214611678573392915050565b61168061235d565b507fffffffffffffffffffffffff0000000000000000000000000000000000000000919050565b82516060906000906116bb6004600261342b565b60ff166116c89190613454565b905060008451826116d99190613454565b905060016116e96004600261342b565b60ff1683838989896040516020016117079796959493929190613471565b604051602081830303815290604052925050509392505050565b61172c6000826123c4565b6021611738600061154f565b8154600181018355600092835260209092209091015550565b81516000906020840161176c64ffffffffff851682846124e7565b95945050505050565b600061074462ffffff1983168260288161252e565b600061074460286117ad81601886901c6bffffffffffffffffffffffff16613383565b62ffffff1985169190600061252e565b60606000806117da8460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060405191508192506117ff84836020016125b2565b508181016020016040529052919050565b60008061182262ffffff19851661274d565b905061187b816040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061188781846127aa565b949350505050565b600061074462ffffff19831682600461192b565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168363ffffffff16146119205760405162461bcd60e51b815260206004820152600c60248201527f57726f6e6720646f6d61696e00000000000000000000000000000000000000006044820152606401610609565b61121760b8836127ce565b600061193882602061350f565b61194390600861342b565b60ff1661195185858561195b565b901c949350505050565b60008160ff1660000361197057506000611217565b6119888460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119a360ff841685613532565b1115611a1b57611a026119c48560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff166119ea8660181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16858560ff166127fd565b60405162461bcd60e51b8152600401610609919061354a565b60208260ff161115611a955760405162461bcd60e51b815260206004820152603a60248201527f54797065644d656d566965772f696e646578202d20417474656d70746564207460448201527f6f20696e646578206d6f7265207468616e2033322062797465730000000000006064820152608401610609565b600882026000611ab38660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060007f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84011d91909501511695945050505050565b6000826000018281548110611b3057611b3061327c565b9060005260206000200154905092915050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b9357602002820191906000526020600020905b815481526020019060010190808311611b7f575b50505050509050919050565b60006112178373ffffffffffffffffffffffffffffffffffffffff841661286b565b605254610100900460ff16611c3e5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610609565b6107b133611562565b611c4f612f89565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b60208110156121c357600182821c81169081900361216f5785826020811061213c5761213c61327c565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506121ba565b838583602081106121825761218261327c565b60200201516040516020016121a1929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b50600101612112565b505092915050565b60006121d783836128ba565b6122c55760006121f66121ea8560d81c90565b64ffffffffff166128dd565b915050600061220b8464ffffffffff166128dd565b6040517f5479706520617373657274696f6e206661696c65642e20476f7420307800000060208201527fffffffffffffffffffff0000000000000000000000000000000000000000000060b086811b8216603d8401527f2e20457870656374656420307800000000000000000000000000000000000000604784015283901b16605482015290925060009150605e0160405160208183030381529060405290508060405162461bcd60e51b8152600401610609919061354a565b5090919050565b6000816122d960026115ef565b506122ed62ffffff1984166026600c61192b565b63ffffffff169392505050565b60008161230760026115ef565b506122ed62ffffff198416601a600c61192b565b60008161232860026115ef565b506122ed62ffffff198416600e600c61192b565b60008161234960026115ef565b506122ed62ffffff1984166002600c61192b565b60b75473ffffffffffffffffffffffffffffffffffffffff1633146107b15760405162461bcd60e51b815260206004820152601060248201527f2173797374656d4d657373656e676572000000000000000000000000000000006044820152606401610609565b602080830154906001906123d9906002613675565b6123e39190613383565b81106124315760405162461bcd60e51b815260206004820152601060248201527f6d65726b6c6520747265652066756c6c000000000000000000000000000000006044820152606401610609565b6001016020830181905560005b60208110156124d9578160011660010361246d57828482602081106124655761246561327c565b015550505050565b83816020811061247f5761247f61327c565b01546040805160208101929092528101849052606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209250600191821c910161243e565b506124e2613681565b505050565b6000806124f48385613532565b9050604051811115612504575060005b806000036125195762ffffff19915050611217565b5050606092831b9190911790911b1760181b90565b6000806125498660781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169050612562866129c7565b8461256d8784613532565b6125779190613532565b111561258a5762ffffff19915050611887565b6125948582613532565b90506125a88364ffffffffff1682866124e7565b9695505050505050565b600062ffffff198084160361262f5760405162461bcd60e51b815260206004820152602860248201527f54797065644d656d566965772f636f7079546f202d204e756c6c20706f696e7460448201527f65722064657265660000000000000000000000000000000000000000000000006064820152608401610609565b61263883612a0f565b6126aa5760405162461bcd60e51b815260206004820152602b60248201527f54797065644d656d566965772f636f7079546f202d20496e76616c696420706f60448201527f696e7465722064657265660000000000000000000000000000000000000000006064820152608401610609565b60006126c48460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006126ee8560781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006040519050848111156127135760206060fd5b8285848460045afa506125a86127298760d81c90565b70ffffffffff000000000000000000000000606091821b168717901b841760181b90565b6000806127688360781c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff16905060006127928460181c6bffffffffffffffffffffffff1690565b6bffffffffffffffffffffffff169091209392505050565b60008060006127b98585612a4c565b915091506127c681612aba565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515611217565b6060600061280a866128dd565b9150506000612818866128dd565b9150506000612826866128dd565b9150506000612834866128dd565b9150508383838360405160200161284e94939291906136b0565b604051602081830303815290604052945050505050949350505050565b60008181526001830160205260408120546128b257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610744565b506000610744565b60008164ffffffffff166128ce8460d81c90565b64ffffffffff16149392505050565b600080601f5b600f8160ff1611156129505760006128fc82600861342b565b60ff1685901c905061290d81612ca6565b61ffff16841793508160ff1660101461292857601084901b93505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016128e3565b50600f5b60ff8160ff1610156129c157600061296d82600861342b565b60ff1685901c905061297e81612ca6565b61ffff16831792508160ff1660001461299957601083901b92505b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612954565b50915091565b60006129e18260181c6bffffffffffffffffffffffff1690565b6129f98360781c6bffffffffffffffffffffffff1690565b016bffffffffffffffffffffffff169050919050565b6000612a1b8260d81c90565b64ffffffffff1664ffffffffff03612a3557506000919050565b6000612a40836129c7565b60405110199392505050565b6000808251604103612a825760208301516040840151606085015160001a612a7687828585612cd8565b94509450505050612ab3565b8251604003612aab5760208301516040840151612aa0868383612df0565b935093505050612ab3565b506000905060025b9250929050565b6000816004811115612ace57612ace613169565b03612ad65750565b6001816004811115612aea57612aea613169565b03612b375760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610609565b6002816004811115612b4b57612b4b613169565b03612b985760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610609565b6003816004811115612bac57612bac613169565b03612c1f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6004816004811115612c3357612c33613169565b036108505760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610609565b6000612cb860048360ff16901c612e42565b60ff1661ffff919091161760081b612ccf82612e42565b60ff1617919050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612d0f5750600090506003612de7565b8460ff16601b14158015612d2757508460ff16601c14155b15612d385750600090506004612de7565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612d8c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612de057600060019250925050612de7565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831681612e2660ff86901c601b613532565b9050612e3487828885612cd8565b935093505050935093915050565b600060f08083179060ff82169003612e5d5750603092915050565b8060ff1660f103612e715750603192915050565b8060ff1660f203612e855750603292915050565b8060ff1660f303612e995750603392915050565b8060ff1660f403612ead5750603492915050565b8060ff1660f503612ec15750603592915050565b8060ff1660f603612ed55750603692915050565b8060ff1660f703612ee95750603792915050565b8060ff1660f803612efd5750603892915050565b8060ff1660f903612f115750603992915050565b8060ff1660fa03612f255750606192915050565b8060ff1660fb03612f395750606292915050565b8060ff1660fc03612f4d5750606392915050565b8060ff1660fd03612f615750606492915050565b8060ff1660fe03612f755750606592915050565b8060ff1660ff036116425750606692915050565b6040518061040001604052806020906020820280368337509192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112612fe857600080fd5b813567ffffffffffffffff8082111561300357613003612fa8565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561304957613049612fa8565b8160405283815286602085880101111561306257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60006020828403121561309457600080fd5b813567ffffffffffffffff8111156130ab57600080fd5b61188784828501612fd7565b6000602082840312156130c957600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff8116811461085057600080fd5b60006020828403121561310457600080fd5b8135611217816130d0565b6020808252825182820181905260009190848201906040850190845b8181101561315d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161312b565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208101600383106131d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b803563ffffffff811681146106da57600080fd5b600080600080600060a0868803121561320557600080fd5b61320e866131d9565b945060208601359350613223604087016131d9565b9250606086013567ffffffffffffffff8082111561324057600080fd5b61324c89838a01612fd7565b9350608088013591508082111561326257600080fd5b5061326f88828901612fd7565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b838110156132c65781810151838201526020016132ae565b838111156132d5576000848401525b50505050565b600081518084526132f38160208601602086016132ab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8316815260406020820152600061188760408301846132db565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561339557613395613354565b500390565b6000602082840312156133ac57600080fd5b8151611217816130d0565b600063ffffffff8083168185168083038211156133d6576133d6613354565b01949350505050565b6040815260006133f260408301856132db565b828103602084015261176c81856132db565b60006bffffffffffffffffffffffff8083168185168083038211156133d6576133d6613354565b600060ff821660ff84168160ff048111821515161561344c5761344c613354565b029392505050565b600061ffff8083168185168083038211156133d6576133d6613354565b60007fffff000000000000000000000000000000000000000000000000000000000000808a60f01b168352808960f01b166002840152808860f01b166004840152808760f01b1660068401525084516134d18160088501602089016132ab565b8451908301906134e88160088401602089016132ab565b84519101906134fe8160088401602088016132ab565b016008019998505050505050505050565b600060ff821660ff84168082101561352957613529613354565b90039392505050565b6000821982111561354557613545613354565b500190565b60208152600061121760208301846132db565b600181815b808511156135b657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561359c5761359c613354565b808516156135a957918102915b93841c9390800290613562565b509250929050565b6000826135cd57506001610744565b816135da57506000610744565b81600181146135f057600281146135fa57613616565b6001915050610744565b60ff84111561360b5761360b613354565b50506001821b610744565b5060208310610133831016604e8410600b8410161715613639575081810a610744565b613643838361355d565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561344c5761344c613354565b600061121783836135be565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f54797065644d656d566965772f696e646578202d204f76657272616e2074686581527f20766965772e20536c696365206973206174203078000000000000000000000060208201527fffffffffffff000000000000000000000000000000000000000000000000000060d086811b821660358401527f2077697468206c656e6774682030780000000000000000000000000000000000603b840181905286821b8316604a8501527f2e20417474656d7074656420746f20696e646578206174206f6666736574203060508501527f7800000000000000000000000000000000000000000000000000000000000000607085015285821b83166071850152607784015283901b1660868201527f2e00000000000000000000000000000000000000000000000000000000000000608c8201526000608d82016125a856fea2646970667358221220ba13c1faec0e4c3a099925d7c203efd3f588ac7f865d7d75c54f5d2a2b204e3564736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"125308:12373:0:-:0;;;128362:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;113181:26;;;;;;62842:30;;125308:12373;;14:280:1;83:6;136:2;124:9;115:7;111:23;107:32;104:52;;;152:1;149;142:12;104:52;184:9;178:16;234:10;227:5;223:22;216:5;213:33;203:61;;260:1;257;250:12;203:61;283:5;14:280;-1:-1:-1;;;14:280:1:o;:::-;125308:12373:0;;;;;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"125308:12373:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116880:81;;;;;;;;;;-1:-1:-1;116944:10:0;;116880:81;;;160:25:1;;;148:2;133:18;116880:81:0;;;;;;;;134209:780;;;;;;;;;;-1:-1:-1;134209:780:0;;;;;:::i;:::-;;:::i;:::-;;;1657:14:1;;1650:22;1632:41;;1620:2;1605:18;134209:780:0;1492:187:1;67986:95:0;;;;;;;;;;;;;:::i;132658:257::-;;;;;;;;;;;;;:::i;:::-;;;;1886:10:1;1874:23;;;1856:42;;1929:2;1914:18;;1907:34;;;;1829:18;132658:257:0;1684:263:1;126214:58:0;;;;;;;;;;;;126263:9;126214:58;;67873:107;;;;;;;;;;-1:-1:-1;67873:107:0;;;;;:::i;:::-;;:::i;:::-;;;2313:42:1;2301:55;;;2283:74;;2271:2;2256:18;67873:107:0;2137:226:1;115497:57:0;;;;;;;;;;;;;:::i;:::-;;116424:32;;;;;;;;;;-1:-1:-1;116424:32:0;;;;;:::i;:::-;;:::i;111970:35::-;;;;;;;;;;;;;;;;;;2724:10:1;2712:23;;;2694:42;;2682:2;2667:18;111970:35:0;2550:192:1;109653:85:0;;;;;;;;;;-1:-1:-1;109725:6:0;;;;109653:85;;63652:99;;;;;;;;;;;;;:::i;130299:140::-;;;;;;;;;;-1:-1:-1;130299:140:0;;;;;:::i;:::-;;:::i;63425:105::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;129627:253::-;;;;;;;;;;-1:-1:-1;129627:253:0;;;;;:::i;:::-;;:::i;126487:37::-;;;;;;;;;;-1:-1:-1;126487:37:0;;;;;;;;;;;67766:101;;;;;;;;;;;;;:::i;126391:19::-;;;;;;;;;;-1:-1:-1;126391:19:0;;;;;;;;115171:133;;;;;;;;;;-1:-1:-1;115171:133:0;;;;;:::i;:::-;;:::i;63536:110::-;;;;;;;;;;-1:-1:-1;63536:110:0;;;;;:::i;:::-;;:::i;126563:19::-;;;;;;;;;;-1:-1:-1;126563:19:0;;;;;;;;;;;;;;;;;;:::i;128573:354::-;;;;;;;;;;-1:-1:-1;128573:354:0;;;;;:::i;:::-;;:::i;112552:39::-;;;;;;;;;;-1:-1:-1;112552:39:0;;;;;;;;116696:81;;;;;;;;;;;;;:::i;110535:198::-;;;;;;;;;;-1:-1:-1;110535:198:0;;;;;:::i;:::-;;:::i;130945:1473::-;;;;;;:::i;:::-;;:::i;116392:26::-;;;;;;;;;;-1:-1:-1;116392:26:0;;;;;;201:33;;;;;;;;;;;;233:1;201:33;;;;;6592:4:1;6580:17;;;6562:36;;6550:2;6535:18;201:33:0;6420:184:1;134209:780:0;134291:4;129345:13;129336:5;;;;;;;:22;;;;;;;;:::i;:::-;;129328:47;;;;-1:-1:-1;;;129328:47:0;;6811:2:1;129328:47:0;;;6793:21:1;6850:2;6830:18;;;6823:30;6889:14;6869:18;;;6862:42;6921:18;;129328:47:0;;;;;;;;;134362:15:::1;134379:13:::0;134396:30:::1;134413:12;134396:16;:30::i;:::-;134361:65;;;;134436:13;134452:24;:5;:22;;;;:24::i;:::-;134436:40:::0;-1:-1:-1;134486:13:0::1;134502:23;-1:-1:-1::0;;134502:21:0;::::1;;:23::i;:::-;134610:15;:22:::0;134486:39;;-1:-1:-1;134601:31:0::1;::::0;::::1;;134597:284;;;134661:15;134677:6;134661:23;;;;;;;;;;:::i;:::-;;;;;;;;;134652:5;:32:::0;134648:139:::1;;-1:-1:-1::0;134767:5:0::1;::::0;134209:780;-1:-1:-1;;;;;134209:780:0:o;134648:139::-:1;134890:14;134896:7;134890:5;:14::i;:::-;134919:42;134939:7;134948:12;134919:42;;;;;;;:::i;:::-;;;;;;;;134978:4;134971:11;;;;;;129385:1;134209:780:::0;;;:::o;67986:95::-;68033:7;68059:15;:6;:13;:15::i;:::-;68052:22;;67986:95;:::o;132658:257::-;132763:15;:22;132706:13;;;;132799:11;;132795:114;;132842:10;132851:1;132842:6;:10;:::i;:::-;132826:27;;132875:15;132891:6;132875:23;;;;;;;;;;:::i;:::-;;;;;;;;;132867:31;;132795:114;132736:179;132658:257;;:::o;67873:107::-;67930:7;67956:17;:6;67966;67956:9;:17::i;:::-;67949:24;67873:107;-1:-1:-1;;67873:107:0:o;115497:57::-;109725:6;;109865:23;109725:6;108653:10;109865:23;109857:68;;;;-1:-1:-1;;;109857:68:0;;8586:2:1;109857:68:0;;;8568:21:1;;;8605:18;;;8598:30;8664:34;8644:18;;;8637:62;8716:18;;109857:68:0;8384:356:1;109857:68:0;115497:57::o;116424:32::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116424:32:0;:::o;63652:99::-;63701:7;63727:17;:8;:15;:17::i;130299:140::-;109725:6;;109865:23;109725:6;108653:10;109865:23;109857:68;;;;-1:-1:-1;;;109857:68:0;;8586:2:1;109857:68:0;;;8568:21:1;;;8605:18;;;8598:30;8664:34;8644:18;;;8637:62;8716:18;;109857:68:0;8384:356:1;109857:68:0;130380:52:::1;130415:15;130380:18;:52::i;:::-;130299:140:::0;:::o;63425:105::-;63471:16;63506:17;:8;:15;:17::i;129627:253::-;129141:14;;;;;;;129119:10;:37;129111:65;;;;-1:-1:-1;;;129111:65:0;;8947:2:1;129111:65:0;;;8929:21:1;8986:2;8966:18;;;8959:30;9025:17;9005:18;;;8998:45;9060:18;;129111:65:0;8745:339:1;129111:65:0;129737:20:::1;129748:8;129737:10;:20::i;:::-;-1:-1:-1::0;;129852:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;129627:253::o;67766:101::-;67810:16;67845:15;:6;:13;:15::i;115171:133::-;109725:6;;109865:23;109725:6;108653:10;109865:23;109857:68;;;;-1:-1:-1;;;109857:68:0;;8586:2:1;109857:68:0;;;8568:21:1;;;8605:18;;;8598:30;8664:34;8644:18;;;8637:62;8716:18;;109857:68:0;8384:356:1;109857:68:0;115263:15:::1;:34:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;115171:133::o;63536:110::-;63594:7;63620:19;:8;63632:6;63620:11;:19::i;128573:354::-;104833:19;104855:25;104878:1;104855:22;:25::i;:::-;104833:47;;104894:14;104890:65;;;104924:13;:20;;;;;;;;104890:65;128655:29:::1;:27;:29::i;:::-;128694:35;128713:15;128694:18;:35::i;:::-;128739:36;128750:14;;;;;;;;;;;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;128739:10;:36::i;:::-;-1:-1:-1::0;128785:5:0::1;:21:::0;;;::::1;::::0;::::1;::::0;;128887:15:::1;:33:::0;;-1:-1:-1;128887:33:0;::::1;::::0;;-1:-1:-1;128887:33:0;;;;::::1;::::0;104975:99;;;;105009:13;:21;;;;;;105049:14;;-1:-1:-1;6562:36:1;;105049:14:0;;6550:2:1;6535:18;105049:14:0;;;;;;;104975:99;104823:257;128573:354;:::o;116696:81::-;116733:7;116759:11;:4;:9;:11::i;110535:198::-;109725:6;;109865:23;109725:6;108653:10;109865:23;109857:68;;;;-1:-1:-1;;;109857:68:0;;8586:2:1;109857:68:0;;;8568:21:1;;;8605:18;;;8598:30;8664:34;8644:18;;;8637:62;8716:18;;109857:68:0;8384:356:1;109857:68:0;110623:22:::1;::::0;::::1;110615:73;;;::::0;-1:-1:-1;;;110615:73:0;;9746:2:1;110615:73:0::1;::::0;::::1;9728:21:1::0;9785:2;9765:18;;;9758:30;9824:34;9804:18;;;9797:62;9895:8;9875:18;;;9868:36;9921:19;;110615:73:0::1;9544:402:1::0;110615:73:0::1;110698:28;110717:8;110698:18;:28::i;130945:1473::-:0;129345:13;129336:5;;;;;;;:22;;;;;;;;:::i;:::-;;129328:47;;;;-1:-1:-1;;;129328:47:0;;6811:2:1;129328:47:0;;;6793:21:1;6850:2;6830:18;;;6823:30;6889:14;6869:18;;;6862:42;6921:18;;129328:47:0;6609:336:1;129328:47:0;126263:9:::1;131182:12;:19;:45;;131174:70;;;::::0;-1:-1:-1;;;131174:70:0;;10153:2:1;131174:70:0::1;::::0;::::1;10135:21:1::0;10192:2;10172:18;;;10165:30;10231:14;10211:18;;;10204:42;10263:18;;131174:70:0::1;9951:336:1::0;131174:70:0::1;131294:9;131262:28;:16;:5;:14;:16::i;:::-;-1:-1:-1::0;;131262:26:0::1;;:28::i;:::-;:41;;;131254:59;;;::::0;-1:-1:-1;;;131254:59:0;;10494:2:1;131254:59:0::1;::::0;::::1;10476:21:1::0;10533:1;10513:18;;;10506:29;10571:7;10551:18;;;10544:35;10596:18;;131254:59:0::1;10292:328:1::0;131254:59:0::1;131407:5;::::0;:9:::1;::::0;:5:::1;;::::0;:9:::1;:::i;:::-;131399:5;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;131444:41:0::1;131467:17:::0;131444:22:::1;:41::i;:::-;131645:5;::::0;79579:242;;;13917:16:1;79579:242:0;;;13901:102:1;14022:66;131599:11:0::1;14125:3:1::0;14121:16;;;14117:25;;14104:11;;;14097:46;14159:11;;;14152:27;;;14213:16;;;;;14195:12;;;14188:47;14269:16;;;14265:25;;14251:12;;;14244:47;14307:12;;;14300:28;;;14362:16;;;;14358:25;;;14344:12;;;14337:47;79579:242:0;;;;;;;;;14400:12:1;;;;79579:242:0;;131426:59;;-1:-1:-1;131813:21:0::1;131837:51;131859:7;131868:5;131875:12;131837:21;:51::i;:::-;131979:19:::0;;::::1;::::0;::::1;::::0;131813:75;;-1:-1:-1;132061:25:0::1;131979:19:::0;132061:11:::1;:25::i;:::-;132354:5;::::0;::::1;;136417:2:::0;136393:26;;;;;136392:37;132240:171:::1;;132298:1;132288:7;116944:10:::0;;;116880:81;132288:7:::1;:11;;;;:::i;:::-;132262:12;132240:171;132374:5;132393:8;132240:171;;;;;;;:::i;:::-;;;;;;;;131164:1254;;;;130945:1473:::0;;;;;:::o;47765:470::-;47865:16;;47920:19;:12;47865:16;47920;:19::i;:::-;47912:27;-1:-1:-1;33176:2:0;2883:26;16705:2;16701:16;;;16697:28;34430:37;47949:52;;;;-1:-1:-1;;;47949:52:0;;11442:2:1;47949:52:0;;;11424:21:1;11481:2;11461:18;;;11454:30;11520:20;11500:18;;;11493:48;11558:18;;47949:52:0;11240:342:1;47949:52:0;48022:115;48054:23;-1:-1:-1;;48054:21:0;;;:23::i;:::-;48091:36;:28;-1:-1:-1;;48091:26:0;;;:28::i;:::-;-1:-1:-1;;48091:34:0;;:36::i;:::-;48022:18;:115::i;:::-;48011:126;-1:-1:-1;48155:46:0;48165:25;-1:-1:-1;;48165:23:0;;;:25::i;:::-;48192:8;48155:9;:46::i;:::-;48147:81;;;;-1:-1:-1;;;48147:81:0;;11789:2:1;48147:81:0;;;11771:21:1;11828:2;11808:18;;;11801:30;11867:24;11847:18;;;11840:52;11909:18;;48147:81:0;11587:346:1;48147:81:0;47765:470;;;:::o;34828:136::-;34892:6;34924:32;-1:-1:-1;;34924:15:0;;33070:1;;34924:15;:32::i;35057:124::-;35120:7;35146:28;-1:-1:-1;;35146:11:0;;33117:1;35171:2;35146:11;:28::i;135611:283::-;135733:5;:21;;;;;;;;;;;;135789:48;;;;;135825:10;135789:14;:48;;2283:74:1;135789:14:0;;;;;;;;;;:27;;2256:18:1;;135789:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;135852:35:0;;135876:10;;-1:-1:-1;135852:35:0;;;;-1:-1:-1;135852:35:0;;;;;135611:283;:::o;55939:115::-;56002:7;56028:19;56036:3;51554:18;;51472:107;56396:156;56470:7;56520:22;56524:3;56536:5;56520:3;:22::i;:::-;56512:31;56396:156;-1:-1:-1;;;56396:156:0:o;135163:285::-;118516:19;;;;135243:81;;;;-1:-1:-1;;;135243:81:0;;12387:2:1;135243:81:0;;;12369:21:1;12426:2;12406:18;;;12399:30;12465:26;12445:18;;;12438:54;12509:18;;135243:81:0;12185:348:1;135243:81:0;135334:14;:49;;;;;;;;;;;;;;;;;;135398:43;;2283:74:1;;;135398:43:0;;2271:2:1;2256:18;135398:43:0;;;;;;;135163:285;:::o;57092:257::-;57155:16;57183:22;57208:19;57216:3;57208:7;:19::i;64297:207::-;64352:16;64394:21;:8;64407:7;64394:12;:21::i;:::-;64380:35;;64429:11;64425:73;;;64461:26;;2313:42:1;2301:55;;2283:74;;64461:26:0;;2271:2:1;2256:18;64461:26:0;;;;;;;64297:207;;;:::o;107009:808::-;107406:13;;107073:4;;107406:13;;;;;107402:409;;;107460:7;:12;;107471:1;107460:12;:61;;;;-1:-1:-1;107515:4:0;118516:19;:23;107460:61;107435:166;;;;-1:-1:-1;;;107435:166:0;;12740:2:1;107435:166:0;;;12722:21:1;12779:2;12759:18;;;12752:30;12818:34;12798:18;;;12791:62;12889:16;12869:18;;;12862:44;12923:19;;107435:166:0;12538:410:1;107435:166:0;-1:-1:-1;107622:5:0;;107009:808;-1:-1:-1;107009:808:0:o;107402:409::-;107666:12;;:22;;;;:12;;:22;107658:81;;;;-1:-1:-1;;;107658:81:0;;12740:2:1;107658:81:0;;;12722:21:1;12779:2;12759:18;;;12752:30;12818:34;12798:18;;;12791:62;12889:16;12869:18;;;12862:44;12923:19;;107658:81:0;12538:410:1;107658:81:0;-1:-1:-1;107753:12:0;:22;;;;;;;;;;;;;;;-1:-1:-1;;107009:808:0:o;113760:108::-;106420:13;;;;;;;106412:69;;;;-1:-1:-1;;;106412:69:0;;13155:2:1;106412:69:0;;;13137:21:1;13194:2;13174:18;;;13167:30;13233:34;13213:18;;;13206:62;13304:13;13284:18;;;13277:41;13335:19;;106412:69:0;12953:407:1;106412:69:0;113835:26:::1;:24;:26::i;71297:122::-:0;71354:7;71380:32;71392:5;71399:12;:10;:12::i;:::-;71380:11;:32::i;110887:187::-;110979:6;;;;110995:17;;;;;;;;;;;111027:40;;110979:6;;;110995:17;110979:6;;111027:40;;110960:16;;111027:40;110950:124;110887:187;:::o;88279:122::-;88340:7;88366:28;:5;82301:10;88366:9;:28::i;89386:183::-;89459:6;89443:5;87286:35;82301:10;82294:18;-1:-1:-1;;87286:16:0;;;;:35::i;:::-;;89543:19:::1;89556:5;89543:12;:19::i;:::-;89524:16;89534:5;89524:9;:16::i;:::-;89504:17;89515:5;89504:10;:17::i;:::-;89484;89495:5;89484:10;:17::i;:::-;:37;;;;:::i;:::-;:56;;;;:::i;:::-;:78;;;;:::i;:::-;89477:85;;87331:1;89386:183:::0;;;;:::o;136865:814::-;136971:14;90204:24;137005:48;;137001:672;;137105:10;137069:47;134209:780;-1:-1:-1;;134209:780:0:o;137001:672::-;137509:24;:22;:24::i;:::-;-1:-1:-1;90204:24:0;136865:814;;;:::o;83486:638::-;83782:14;;83631:12;;83739:17;;83237:29;83255:10;83108:1;83237:29;:::i;:::-;83759:13;;:38;;;;:::i;:::-;83739:58;;83807:17;83847:5;:12;83827:10;:33;;;;:::i;:::-;83807:53;-1:-1:-1;81958:1:0;83237:29;83255:10;83108:1;83237:29;:::i;:::-;83956:13;;83987:10;84015;84043:7;84068:5;84091:12;83889:228;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;83870:247;;;;83486:638;;;;;:::o;117118:123::-;117173:18;:4;117185:5;117173:11;:18::i;:::-;117201:15;117222:11;:4;:9;:11::i;:::-;117201:33;;;;;;;-1:-1:-1;117201:33:0;;;;;;;;;;;-1:-1:-1;117118:123:0:o;13868:359::-;13972:10;;13938:7;;14119:4;14110:14;;14194:26;;;;14110:14;13972:10;14194:5;:26::i;:::-;14187:33;13868:359;-1:-1:-1;;;;;13868:359:0:o;35287:155::-;35350:7;35376:59;-1:-1:-1;;35376:11:0;;35350:7;33176:2;35350:7;35376:11;:59::i;35525:172::-;35593:7;35619:71;33176:2;35649:37;33176:2;16705;16701:16;;;2883:26;16697:28;35649:37;:::i;:::-;-1:-1:-1;;35619:11:0;;;:71;35688:1;35619:11;:71::i;28521:632::-;28576:16;28604:11;28625:12;28640;28644:7;16705:2;16701:16;2883:26;16697:28;;16459:282;28640:12;28625:27;;;;28762:4;28756:11;28749:18;;28817:3;28810:10;;28863:33;28876:7;28885:3;28891:4;28885:10;28863:12;:33::i;:::-;-1:-1:-1;29020:14:0;;;29036:4;29016:25;29010:4;29003:39;29083:17;;28521:632;;-1:-1:-1;28521:632:0:o;46929:285::-;47039:14;;47086;-1:-1:-1;;47086:12:0;;;:14::i;:::-;47069:31;;47119:36;47148:6;45522:58;;21667:66:1;45522:58:0;;;21655:79:1;21750:12;;;21743:28;;;45392:7:0;;21787:12:1;;45522:58:0;;;;;;;;;;;;45512:69;;;;;;45505:76;;45323:265;;;;47119:36;47110:45;;47174:33;47188:6;47196:10;47174:13;:33::i;:::-;47165:42;46929:285;-1:-1:-1;;;;46929:285:0:o;34571:143::-;34636:6;34668:38;-1:-1:-1;;34668:15:0;;34636:6;34704:1;34668:15;:38::i;64737:199::-;64821:4;64856:13;64845:24;;:7;:24;;;64837:49;;;;-1:-1:-1;;;64837:49:0;;16175:2:1;64837:49:0;;;16157:21:1;16214:2;16194:18;;;16187:30;16253:14;16233:18;;;16226:42;16285:18;;64837:49:0;15973:336:1;64837:49:0;64903:26;:8;64921:7;64903:17;:26::i;21334:221::-;21453:14;21531:11;21536:6;21531:2;:11;:::i;:::-;21530:17;;21546:1;21530:17;:::i;:::-;21486:62;;21494:30;21500:7;21509:6;21517;21494:5;:30::i;:::-;21486:62;;;21334:221;-1:-1:-1;;;;21334:221:0:o;20217:771::-;20332:14;20362:6;:11;;20372:1;20362:11;20358:59;;-1:-1:-1;20404:1:0;20389:17;;20358:59;20448:12;20452:7;16705:2;16701:16;2883:26;16697:28;;16459:282;20448:12;20430:30;;:15;;;;:6;:15;:::i;:::-;:30;20426:137;;;20483:68;20499:12;20503:7;15599:3;15595:17;2883:26;15591:29;;15272:364;20499:12;20483:68;;20513:12;20517:7;16705:2;16701:16;2883:26;16697:28;;16459:282;20513:12;20483:68;;20527:6;20543;20535:15;;20483;:68::i;:::-;20476:76;;-1:-1:-1;;;20476:76:0;;;;;;;;:::i;20426:137::-;20590:2;20580:6;:12;;;;20572:83;;;;-1:-1:-1;;;20572:83:0;;17073:2:1;20572:83:0;;;17055:21:1;17112:2;17092:18;;;17085:30;17151:34;17131:18;;;17124:62;17222:28;17202:18;;;17195:56;17268:19;;20572:83:0;16871:422:1;20572:83:0;20736:1;20727:10;;20666:15;20772:12;20776:7;15599:3;15595:17;2883:26;15591:29;;15272:364;20772:12;20757:27;;;-1:-1:-1;20794:13:0;7701:66;7671:12;;;7650:131;20946:17;;;;20940:24;20936:36;;;-1:-1:-1;;;;;20217:771:0:o;51921:118::-;51988:7;52014:3;:11;;52026:5;52014:18;;;;;;;;:::i;:::-;;;;;;;;;52007:25;;51921:118;;;;:::o;52579:109::-;52635:16;52670:3;:11;;52663:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52579:109;;;:::o;55138:150::-;55208:4;55231:50;55236:3;55256:23;;;55231:4;:50::i;109466:111::-;106420:13;;;;;;;106412:69;;;;-1:-1:-1;;;106412:69:0;;13155:2:1;106412:69:0;;;13137:21:1;13194:2;13174:18;;;13167:30;13233:34;13213:18;;;13206:62;13304:13;13284:18;;;13277:41;13335:19;;106412:69:0;12953:407:1;106412:69:0;109538:32:::1;108653:10:::0;109538:18:::1;:32::i;71537:964::-:0;71582:34;;:::i;:::-;71641:3;71628:16;;71667:3;71628:10;71654;;:16;71693:3;71680:10;;;:16;71719:3;71706:10;;;:16;71745:3;71732:10;;;:16;71771:3;71758:10;;;:16;71797:3;71784:10;;;:16;71823:3;71810:10;;;:16;71849:3;71836:10;;;:16;71875:3;71862:10;;;:16;71902:4;71888:11;;;:18;71930:4;71916:11;;;:18;71958:4;71944:11;;;:18;71986:4;71972:11;;;:18;72014:4;72000:11;;;:18;72042:4;72028:11;;;:18;72070:4;72056:11;;;:18;72098:4;72084:11;;;:18;72126:4;72112:11;;;:18;72154:4;72140:11;;;:18;72182:4;72168:11;;;:18;72210:4;72196:11;;;:18;72238:4;72224:11;;;:18;72266:4;72252:11;;;:18;72294:4;72280:11;;;:18;72322:4;72308:11;;;:18;72350:4;72336:11;;;:18;72378:4;72364:11;;;:18;72406:4;72392:11;;;:18;72434:4;72420:11;;;:18;72462:4;72448:11;;;:18;72490:4;72476:11;;;:18;71628:7;71537:964::o;70641:589::-;70814:11;;;;70765:16;;;70836:388;69221:2;70856:1;:14;70836:388;;;70922:4;70907:11;;;70906:20;;;70944:12;;;70940:215;;71014:5;71027:1;71014:15;;;;;;;:::i;:::-;;;70997:43;;;;;;17455:19:1;;;;17490:12;;17483:28;;;17527:12;;70997:43:0;;;;;;;;;;;;70987:54;;;;;;70976:65;;70940:215;;;71118:8;71128:7;71136:1;71128:10;;;;;;;:::i;:::-;;;;;71101:38;;;;;;;;17455:19:1;;;17499:2;17490:12;;17483:28;17536:2;17527:12;;17298:247;71101:38:0;;;;;;;;;;;;;71091:49;;;;;;71080:60;;70940:215;-1:-1:-1;71196:3:0;;70836:388;;;;70787:443;70641:589;;;;:::o;10286:578::-;10364:7;10388:26;10395:7;10404:9;10388:6;:26::i;:::-;10383:451;;10433:9;10446:35;10464:15;10471:7;14630:3;14626:17;;14419:268;10464:15;10456:24;;10446:9;:35::i;:::-;10430:51;;;10498:9;10511:29;10529:9;10521:18;;10511:9;:29::i;:::-;10598:186;;17917:31:1;10598:186:0;;;17905:44:1;17968:66;18072:3;18068:16;;;18064:25;;18050:12;;;18043:47;18120:15;18106:12;;;18099:37;18170:16;;;18166:25;18152:12;;;18145:47;10495:45:0;;-1:-1:-1;10554:17:0;;-1:-1:-1;18208:12:1;;10598:186:0;;;;;;;;;;;;10554:244;;10819:3;10812:11;;-1:-1:-1;;;10812:11:0;;;;;;;;:::i;10383:451::-;-1:-1:-1;10850:7:0;;10286:578;-1:-1:-1;10286:578:0:o;89227:153::-;89303:6;89287:5;87286:35;82301:10;82294:18;;87286:35;-1:-1:-1;89335:37:0::1;-1:-1:-1::0;;89335:15:0;::::1;87234:2;89369;89335:15;:37::i;:::-;89321:52;;::::0;89227:153;-1:-1:-1;;;89227:153:0:o;89031:147::-;89104:6;89088:5;87286:35;82301:10;82294:18;;87286:35;-1:-1:-1;89136:34:0::1;-1:-1:-1::0;;89136:15:0;::::1;87181:2;89167;89136:15;:34::i;88836:149::-:0;88910:6;88894:5;87286:35;82301:10;82294:18;;87286:35;-1:-1:-1;88942:35:0::1;-1:-1:-1::0;;88942:15:0;::::1;87131:2;88974;88942:15;:35::i;88640:149::-:0;88714:6;88698:5;87286:35;82301:10;82294:18;;87286:35;-1:-1:-1;88746:35:0::1;-1:-1:-1::0;;88746:15:0;::::1;87081:1;88778:2;88746:15;:35::i;116139:132::-:0;116227:15;;;;116205:10;:38;116197:67;;;;-1:-1:-1;;;116197:67:0;;18433:2:1;116197:67:0;;;18415:21:1;18472:2;18452:18;;;18445:30;18511:18;18491;;;18484:46;18547:18;;116197:67:0;18231:340:1;69680:750:0;69765:11;;;;;;69284:1;;69268:13;;:1;:13;:::i;:::-;:17;;;;:::i;:::-;69794:4;:17;69786:46;;;;-1:-1:-1;;;69786:46:0;;20272:2:1;69786:46:0;;;20254:21:1;20311:2;20291:18;;;20284:30;20350:18;20330;;;20323:46;20386:18;;69786:46:0;20070:340:1;69786:46:0;69867:6;;69893:11;;;:18;;;69926:9;69921:319;69221:2;69941:1;:14;69921:319;;;69978:4;69985:1;69978:8;69991:1;69977:15;69973:101;;70030:5;70012;70025:1;70012:15;;;;;;;:::i;:::-;;:23;-1:-1:-1;;;;69680:750:0:o;69973:101::-;70122:5;70135:1;70122:15;;;;;;;:::i;:::-;;;70105:40;;;;;;17455:19:1;;;;17490:12;;17483:28;;;17527:12;;70105:40:0;;;;;;;;;;;;;70095:51;;70105:40;70095:51;;;;;-1:-1:-1;70169:1:0;70160:10;;;;70212:3;69921:319;;;-1:-1:-1;70410:13:0;;:::i;:::-;69740:690;69680:750;;:::o;13009:462::-;13120:15;;13162:11;13169:4;13162;:11;:::i;:::-;13147:26;;13288:4;13282:11;13276:4;13273:21;13270:66;;;-1:-1:-1;13321:1:0;13270:66;13359:4;13367:1;13359:9;13355:51;;-1:-1:-1;;13384:11:0;;;;;13355:51;-1:-1:-1;;12278:2:0;12274:27;;;12348:17;;;;12340:26;;;12412:17;12408:2;12404:26;;13009:462::o;17342:399::-;17481:7;17500:12;17515;17519:7;15599:3;15595:17;2883:26;15591:29;;15272:364;17515:12;17500:27;;;;17611:12;17615:7;17611:3;:12::i;:::-;17604:4;17588:13;17595:6;17588:4;:13;:::i;:::-;:20;;;;:::i;:::-;:35;17584:77;;;-1:-1:-1;;17639:11:0;;;;;17584:77;17678:13;17685:6;17678:4;:13;:::i;:::-;17671:20;;17708:26;17714:7;17708:26;;17723:4;17729;17708:5;:26::i;:::-;17701:33;17342:399;-1:-1:-1;;;;;;17342:399:0:o;27249:902::-;27327:15;-1:-1:-1;;8185:15:0;;;;27354:69;;;;-1:-1:-1;;;27354:69:0;;20806:2:1;27354:69:0;;;20788:21:1;20845:2;20825:18;;;20818:30;20884:34;20864:18;;;20857:62;20955:10;20935:18;;;20928:38;20983:19;;27354:69:0;20604:404:1;27354:69:0;27441:16;27449:7;27441;:16::i;:::-;27433:72;;;;-1:-1:-1;;;27433:72:0;;21215:2:1;27433:72:0;;;21197:21:1;21254:2;21234:18;;;21227:30;21293:34;21273:18;;;21266:62;21364:13;21344:18;;;21337:41;21395:19;;27433:72:0;21013:407:1;27433:72:0;27515:12;27530;27534:7;16705:2;16701:16;2883:26;16697:28;;16459:282;27530:12;27515:27;;;;27552:15;27570:12;27574:7;15599:3;15595:17;2883:26;15591:29;;15272:364;27570:12;27552:30;;;;27593:11;27714:4;27708:11;27701:18;;27801:7;27796:3;27793:16;27790:94;;;27841:4;27835;27828:18;27790:94;28056:4;28047:7;28041:4;28032:7;28029:1;28022:5;28011:50;28007:55;28092:52;28113:15;28120:7;14630:3;14626:17;;14419:268;28113:15;12274:27;12278:2;12274:27;;;;12348:17;;12340:26;;12412:17;;12408:2;12404:26;;12024:446;22668:290;22724:14;22750:12;22765;22769:7;15599:3;15595:17;2883:26;15591:29;;15272:364;22765:12;22750:27;;;;22787:12;22802;22806:7;16705:2;16701:16;2883:26;16697:28;;16459:282;22802:12;22787:27;;22921:21;;;;22668:290;-1:-1:-1;;;22668:290:0:o;41619:227::-;41697:7;41717:17;41736:18;41758:27;41769:4;41775:9;41758:10;:27::i;:::-;41716:69;;;;41795:18;41807:5;41795:11;:18::i;:::-;-1:-1:-1;41830:9:0;41619:227;-1:-1:-1;;;41619:227:0:o;55693:165::-;55826:23;;;55773:4;51360:19;;;:12;;;:19;;;;;;:24;;55796:55;51264:127;18974:741;19120:17;19152:9;19165:15;19175:4;19165:9;:15::i;:::-;19149:31;;;19193:9;19206:15;19216:4;19206:9;:15::i;:::-;19190:31;;;19234:9;19247:17;19257:6;19247:9;:17::i;:::-;19231:33;;;19277:9;19290:17;19300:6;19290:9;:17::i;:::-;19274:33;;;19457:1;19519;19599;19661;19343:355;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19317:391;;19139:576;;;;18974:741;;;;;;:::o;49223:404::-;49286:4;51360:19;;;:12;;;:19;;;;;;49302:319;;-1:-1:-1;49344:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;49524:18;;49502:19;;;:12;;;:19;;;;;;:40;;;;49556:11;;49302:319;-1:-1:-1;49605:5:0;49598:12;;9856:132;9930:4;9972:9;9953:28;;:15;9960:7;14630:3;14626:17;;14419:268;9953:15;:28;;;;9856:132;-1:-1:-1;;;9856:132:0:o;5244:667::-;5298:13;;5354:2;5339:258;5362:2;5358:1;:6;;;5339:258;;;5382:11;5409:5;:1;5413;5409:5;:::i;:::-;5402:13;;:2;:13;;5382:34;;5439:14;5447:5;5439:7;:14::i;:::-;5430:23;;;;;;5471:1;:7;;5476:2;5471:7;5467:58;;5508:2;5498:12;;;;;5467:58;-1:-1:-1;5566:6:0;;5339:258;;;-1:-1:-1;5660:2:0;5645:260;5668:3;5664:1;:7;;;5645:260;;;5689:11;5716:5;:1;5720;5716:5;:::i;:::-;5709:13;;:2;:13;;5689:34;;5747:14;5755:5;5747:7;:14::i;:::-;5737:24;;;;;;5779:1;:6;;5784:1;5779:6;5775:58;;5816:2;5805:13;;;;;5775:58;-1:-1:-1;5874:6:0;;5645:260;;;;5244:667;;;:::o;16915:147::-;16968:7;17033:12;17037:7;16705:2;16701:16;2883:26;16697:28;;16459:282;17033:12;17018;17022:7;15599:3;15595:17;2883:26;15591:29;;15272:364;17018:12;:27;17011:34;;;;16915:147;;;:::o;8858:333::-;8915:8;8939:15;8946:7;14630:3;14626:17;;14419:268;8939:15;:31;;8958:12;8939:31;8935:74;;-1:-1:-1;8993:5:0;;8858:333;-1:-1:-1;8858:333:0:o;8935:74::-;9018:12;9033;9037:7;9033:3;:12::i;:::-;9168:4;9162:11;-1:-1:-1;9149:26:0;;8858:333;-1:-1:-1;;;8858:333:0:o;39554:1279::-;39635:7;39644:12;39865:9;:16;39885:2;39865:22;39861:966;;40154:4;40139:20;;40133:27;40203:4;40188:20;;40182:27;40260:4;40245:20;;40239:27;39903:9;40231:36;40301:25;40312:4;40231:36;40133:27;40182;40301:10;:25::i;:::-;40294:32;;;;;;;;;39861:966;40347:9;:16;40367:2;40347:22;40343:484;;40616:4;40601:20;;40595:27;40666:4;40651:20;;40645:27;40706:23;40717:4;40595:27;40645;40706:10;:23::i;:::-;40699:30;;;;;;;;40343:484;-1:-1:-1;40776:1:0;;-1:-1:-1;40780:35:0;40343:484;39554:1279;;;;;:::o;37859:631::-;37936:20;37927:5;:29;;;;;;;;:::i;:::-;;37923:561;;37859:631;:::o;37923:561::-;38032:29;38023:5;:38;;;;;;;;:::i;:::-;;38019:465;;38077:34;;-1:-1:-1;;;38077:34:0;;23527:2:1;38077:34:0;;;23509:21:1;23566:2;23546:18;;;23539:30;23605:26;23585:18;;;23578:54;23649:18;;38077:34:0;23325:348:1;38019:465:0;38141:35;38132:5;:44;;;;;;;;:::i;:::-;;38128:356;;38192:41;;-1:-1:-1;;;38192:41:0;;23880:2:1;38192:41:0;;;23862:21:1;23919:2;23899:18;;;23892:30;23958:33;23938:18;;;23931:61;24009:18;;38192:41:0;23678:355:1;38128:356:0;38263:30;38254:5;:39;;;;;;;;:::i;:::-;;38250:234;;38309:44;;-1:-1:-1;;;38309:44:0;;24240:2:1;38309:44:0;;;24222:21:1;24279:2;24259:18;;;24252:30;24318:34;24298:18;;;24291:62;24389:4;24369:18;;;24362:32;24411:19;;38309:44:0;24038:398:1;38250:234:0;38383:30;38374:5;:39;;;;;;;;:::i;:::-;;38370:114;;38429:44;;-1:-1:-1;;;38429:44:0;;24643:2:1;38429:44:0;;;24625:21:1;24682:2;24662:18;;;24655:30;24721:34;24701:18;;;24694:62;24792:4;24772:18;;;24765:32;24814:19;;38429:44:0;24441:398:1;4721:199:0;4771:14;4808:18;4824:1;4818:2;:7;;;;4808:9;:18::i;:::-;4797:29;;4850:13;;;;;;4862:1;4850:13;4884;4894:2;4884:9;:13::i;:::-;4873:24;;;;4721:199;-1:-1:-1;4721:199:0:o;43027:1603::-;43153:7;;44077:66;44064:79;;44060:161;;;-1:-1:-1;44175:1:0;;-1:-1:-1;44179:30:0;44159:51;;44060:161;44234:1;:7;;44239:2;44234:7;;:18;;;;;44245:1;:7;;44250:2;44245:7;;44234:18;44230:100;;;-1:-1:-1;44284:1:0;;-1:-1:-1;44288:30:0;44268:51;;44230:100;44441:24;;;44424:14;44441:24;;;;;;;;;25071:25:1;;;25144:4;25132:17;;25112:18;;;25105:45;;;;25166:18;;;25159:34;;;25209:18;;;25202:34;;;44441:24:0;;25043:19:1;;44441:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;44441:24:0;;;;;;-1:-1:-1;;44479:20:0;;;44475:101;;44531:1;44535:29;44515:50;;;;;;;44475:101;44594:6;-1:-1:-1;44602:20:0;;-1:-1:-1;43027:1603:0;;;;;;;;:::o;42100:336::-;42210:7;;42268:66;42255:80;;42210:7;42361:25;42377:3;42362:18;;;42384:2;42361:25;:::i;:::-;42345:42;;42404:25;42415:4;42421:1;42424;42427;42404:10;:25::i;:::-;42397:32;;;;;;42100:336;;;;;;:::o;3156:1393::-;3208:10;3374:4;3369:9;;;;3420:15;;;;;3416:57;;-1:-1:-1;3458:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3416:57::-;3491:7;:15;;3502:4;3491:15;3487:57;;-1:-1:-1;3529:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3487:57::-;3562:7;:15;;3573:4;3562:15;3558:57;;-1:-1:-1;3600:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3558:57::-;3633:7;:15;;3644:4;3633:15;3629:57;;-1:-1:-1;3671:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3629:57::-;3704:7;:15;;3715:4;3704:15;3700:57;;-1:-1:-1;3742:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3700:57::-;3775:7;:15;;3786:4;3775:15;3771:57;;-1:-1:-1;3813:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3771:57::-;3846:7;:15;;3857:4;3846:15;3842:57;;-1:-1:-1;3884:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3842:57::-;3917:7;:15;;3928:4;3917:15;3913:57;;-1:-1:-1;3955:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3913:57::-;3988:7;:15;;3999:4;3988:15;3984:57;;-1:-1:-1;4026:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;3984:57::-;4059:7;:15;;4070:4;4059:15;4055:57;;-1:-1:-1;4097:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;4055:57::-;4130:7;:15;;4141:4;4130:15;4126:57;;-1:-1:-1;4168:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;4126:57::-;4201:7;:15;;4212:4;4201:15;4197:57;;-1:-1:-1;4239:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;4197:57::-;4272:7;:15;;4283:4;4272:15;4268:57;;-1:-1:-1;4310:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;4268:57::-;4343:7;:15;;4354:4;4343:15;4339:57;;-1:-1:-1;4381:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;4339:57::-;4414:7;:15;;4425:4;4414:15;4410:57;;-1:-1:-1;4452:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;4410:57::-;4485:7;:15;;4496:4;4485:15;4481:57;;-1:-1:-1;4523:4:0;;3156:1393;-1:-1:-1;;3156:1393:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:184:1:-;248:77;245:1;238:88;345:4;342:1;335:15;369:4;366:1;359:15;385:777;427:5;480:3;473:4;465:6;461:17;457:27;447:55;;498:1;495;488:12;447:55;534:6;521:20;560:18;597:2;593;590:10;587:36;;;603:18;;:::i;:::-;737:2;731:9;799:4;791:13;;642:66;787:22;;;811:2;783:31;779:40;767:53;;;835:18;;;855:22;;;832:46;829:72;;;881:18;;:::i;:::-;921:10;917:2;910:22;956:2;948:6;941:18;1002:3;995:4;990:2;982:6;978:15;974:26;971:35;968:55;;;1019:1;1016;1009:12;968:55;1083:2;1076:4;1068:6;1064:17;1057:4;1049:6;1045:17;1032:54;1130:1;1123:4;1118:2;1110:6;1106:15;1102:26;1095:37;1150:6;1141:15;;;;;;385:777;;;;:::o;1167:320::-;1235:6;1288:2;1276:9;1267:7;1263:23;1259:32;1256:52;;;1304:1;1301;1294:12;1256:52;1344:9;1331:23;1377:18;1369:6;1366:30;1363:50;;;1409:1;1406;1399:12;1363:50;1432:49;1473:7;1464:6;1453:9;1449:22;1432:49;:::i;1952:180::-;2011:6;2064:2;2052:9;2043:7;2039:23;2035:32;2032:52;;;2080:1;2077;2070:12;2032:52;-1:-1:-1;2103:23:1;;1952:180;-1:-1:-1;1952:180:1:o;2747:154::-;2833:42;2826:5;2822:54;2815:5;2812:65;2802:93;;2891:1;2888;2881:12;2906:247;2965:6;3018:2;3006:9;2997:7;2993:23;2989:32;2986:52;;;3034:1;3031;3024:12;2986:52;3073:9;3060:23;3092:31;3117:5;3092:31;:::i;3158:681::-;3329:2;3381:21;;;3451:13;;3354:18;;;3473:22;;;3300:4;;3329:2;3552:15;;;;3526:2;3511:18;;;3300:4;3595:218;3609:6;3606:1;3603:13;3595:218;;;3674:13;;3689:42;3670:62;3658:75;;3788:15;;;;3753:12;;;;3631:1;3624:9;3595:218;;;-1:-1:-1;3830:3:1;;3158:681;-1:-1:-1;;;;;;3158:681:1:o;4374:184::-;4426:77;4423:1;4416:88;4523:4;4520:1;4513:15;4547:4;4544:1;4537:15;4563:396;4706:2;4691:18;;4739:1;4728:13;;4718:201;;4775:77;4772:1;4765:88;4876:4;4873:1;4866:15;4904:4;4901:1;4894:15;4718:201;4928:25;;;4563:396;:::o;5494:163::-;5561:20;;5621:10;5610:22;;5600:33;;5590:61;;5647:1;5644;5637:12;5662:753;5773:6;5781;5789;5797;5805;5858:3;5846:9;5837:7;5833:23;5829:33;5826:53;;;5875:1;5872;5865:12;5826:53;5898:28;5916:9;5898:28;:::i;:::-;5888:38;;5973:2;5962:9;5958:18;5945:32;5935:42;;5996:37;6029:2;6018:9;6014:18;5996:37;:::i;:::-;5986:47;;6084:2;6073:9;6069:18;6056:32;6107:18;6148:2;6140:6;6137:14;6134:34;;;6164:1;6161;6154:12;6134:34;6187:49;6228:7;6219:6;6208:9;6204:22;6187:49;:::i;:::-;6177:59;;6289:3;6278:9;6274:19;6261:33;6245:49;;6319:2;6309:8;6306:16;6303:36;;;6335:1;6332;6325:12;6303:36;;6358:51;6401:7;6390:8;6379:9;6375:24;6358:51;:::i;:::-;6348:61;;;5662:753;;;;;;;;:::o;6950:184::-;7002:77;6999:1;6992:88;7099:4;7096:1;7089:15;7123:4;7120:1;7113:15;7139:258;7211:1;7221:113;7235:6;7232:1;7229:13;7221:113;;;7311:11;;;7305:18;7292:11;;;7285:39;7257:2;7250:10;7221:113;;;7352:6;7349:1;7346:13;7343:48;;;7387:1;7378:6;7373:3;7369:16;7362:27;7343:48;;7139:258;;;:::o;7402:316::-;7443:3;7481:5;7475:12;7508:6;7503:3;7496:19;7524:63;7580:6;7573:4;7568:3;7564:14;7557:4;7550:5;7546:16;7524:63;:::i;:::-;7632:2;7620:15;7637:66;7616:88;7607:98;;;;7707:4;7603:109;;7402:316;-1:-1:-1;;7402:316:1:o;7723:337::-;7910:42;7902:6;7898:55;7887:9;7880:74;7990:2;7985;7974:9;7970:18;7963:30;7861:4;8010:44;8050:2;8039:9;8035:18;8027:6;8010:44;:::i;8065:184::-;8117:77;8114:1;8107:88;8214:4;8211:1;8204:15;8238:4;8235:1;8228:15;8254:125;8294:4;8322:1;8319;8316:8;8313:34;;;8327:18;;:::i;:::-;-1:-1:-1;8364:9:1;;8254:125::o;9089:251::-;9159:6;9212:2;9200:9;9191:7;9187:23;9183:32;9180:52;;;9228:1;9225;9218:12;9180:52;9260:9;9254:16;9279:31;9304:5;9279:31;:::i;10625:228::-;10664:3;10692:10;10729:2;10726:1;10722:10;10759:2;10756:1;10752:10;10790:3;10786:2;10782:12;10777:3;10774:21;10771:47;;;10798:18;;:::i;:::-;10834:13;;10625:228;-1:-1:-1;;;;10625:228:1:o;10858:377::-;11051:2;11040:9;11033:21;11014:4;11077:44;11117:2;11106:9;11102:18;11094:6;11077:44;:::i;:::-;11169:9;11161:6;11157:22;11152:2;11141:9;11137:18;11130:50;11197:32;11222:6;11214;11197:32;:::i;13365:244::-;13404:3;13432:26;13485:2;13482:1;13478:10;13515:2;13512:1;13508:10;13546:3;13542:2;13538:12;13533:3;13530:21;13527:47;;;13554:18;;:::i;14423:238::-;14461:7;14501:4;14498:1;14494:12;14533:4;14530:1;14526:12;14593:3;14587:4;14583:14;14578:3;14575:23;14568:3;14561:11;14554:19;14550:49;14547:75;;;14602:18;;:::i;:::-;14642:13;;14423:238;-1:-1:-1;;;14423:238:1:o;14666:224::-;14705:3;14733:6;14766:2;14763:1;14759:10;14796:2;14793:1;14789:10;14827:3;14823:2;14819:12;14814:3;14811:21;14808:47;;;14835:18;;:::i;14895:1073::-;15220:3;15248:66;15357:2;15348:6;15343:3;15339:16;15335:25;15330:3;15323:38;15412:2;15403:6;15398:3;15394:16;15390:25;15386:1;15381:3;15377:11;15370:46;15467:2;15458:6;15453:3;15449:16;15445:25;15441:1;15436:3;15432:11;15425:46;15522:2;15513:6;15508:3;15504:16;15500:25;15496:1;15491:3;15487:11;15480:46;;15555:6;15549:13;15571:61;15625:6;15621:1;15616:3;15612:11;15605:4;15597:6;15593:17;15571:61;:::i;:::-;15692:13;;15651:16;;;;15714:62;15692:13;15763:1;15755:10;;15748:4;15736:17;;15714:62;:::i;:::-;15837:13;;15795:17;;;15859:62;15837:13;15908:1;15900:10;;15893:4;15881:17;;15859:62;:::i;:::-;15941:17;15960:1;15937:25;;14895:1073;-1:-1:-1;;;;;;;;;14895:1073:1:o;16314:195::-;16352:4;16389;16386:1;16382:12;16421:4;16418:1;16414:12;16446:3;16441;16438:12;16435:38;;;16453:18;;:::i;:::-;16490:13;;;16314:195;-1:-1:-1;;;16314:195:1:o;16514:128::-;16554:3;16585:1;16581:6;16578:1;16575:13;16572:39;;;16591:18;;:::i;:::-;-1:-1:-1;16627:9:1;;16514:128::o;16647:219::-;16796:2;16785:9;16778:21;16759:4;16816:44;16856:2;16845:9;16841:18;16833:6;16816:44;:::i;18576:482::-;18665:1;18708:5;18665:1;18722:330;18743:7;18733:8;18730:21;18722:330;;;18862:4;18794:66;18790:77;18784:4;18781:87;18778:113;;;18871:18;;:::i;:::-;18921:7;18911:8;18907:22;18904:55;;;18941:16;;;;18904:55;19020:22;;;;18980:15;;;;18722:330;;;18726:3;18576:482;;;;;:::o;19063:866::-;19112:5;19142:8;19132:80;;-1:-1:-1;19183:1:1;19197:5;;19132:80;19231:4;19221:76;;-1:-1:-1;19268:1:1;19282:5;;19221:76;19313:4;19331:1;19326:59;;;;19399:1;19394:130;;;;19306:218;;19326:59;19356:1;19347:10;;19370:5;;;19394:130;19431:3;19421:8;19418:17;19415:43;;;19438:18;;:::i;:::-;-1:-1:-1;;19494:1:1;19480:16;;19509:5;;19306:218;;19608:2;19598:8;19595:16;19589:3;19583:4;19580:13;19576:36;19570:2;19560:8;19557:16;19552:2;19546:4;19543:12;19539:35;19536:77;19533:159;;;-1:-1:-1;19645:19:1;;;19677:5;;19533:159;19724:34;19749:8;19743:4;19724:34;:::i;:::-;19854:6;19786:66;19782:79;19773:7;19770:92;19767:118;;;19865:18;;:::i;19934:131::-;19994:5;20023:36;20050:8;20044:4;20023:36;:::i;20415:184::-;20467:77;20464:1;20457:88;20564:4;20561:1;20554:15;20588:4;20585:1;20578:15;21929:1391;22651:34;22639:47;;22716:23;22711:2;22702:12;;22695:45;22759:66;22863:3;22859:16;;;22855:25;;22850:2;22841:12;;22834:47;22900:17;22942:2;22933:12;;22926:24;;;22984:16;;;22980:25;;22975:2;22966:12;;22959:47;23036:34;23031:2;23022:12;;23015:56;23102:3;23096;23087:13;;23080:26;23141:16;;;23137:25;;23131:3;23122:13;;23115:48;23188:3;23179:13;;23172:25;23232:16;;;23228:25;23222:3;23213:13;;23206:48;21887:3;23309;23300:13;;21875:16;-1:-1:-1;21907:11:1;;;23270:44;21810:114","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_localDomain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"leafIndex","type":"uint256"},{"indexed":true,"internalType":"uint64","name":"destinationAndNonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"tips","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Dispatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"notary","type":"address"}],"name":"DomainNotaryRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"GuardRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"},{"indexed":false,"internalType":"bytes","name":"attestation","type":"bytes"}],"name":"ImproperAttestation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updaterManager","type":"address"}],"name":"NewUpdaterManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"address","name":"reporter","type":"address"}],"name":"UpdaterSlashed","type":"event"},{"inputs":[],"name":"MAX_MESSAGE_BODY_BYTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allGuards","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allNotaries","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"},{"internalType":"bytes32","name":"_recipientAddress","type":"bytes32"},{"internalType":"uint32","name":"_optimisticSeconds","type":"uint32"},{"internalType":"bytes","name":"_tips","type":"bytes"},{"internalType":"bytes","name":"_messageBody","type":"bytes"}],"name":"dispatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getGuard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNotary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardsAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_attestation","type":"bytes"}],"name":"improperAttestation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IUpdaterManager","name":"_updaterManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notariesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updater","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterManager","type":"address"}],"name":"setUpdaterManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum Home.States","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"suggestUpdate","outputs":[{"internalType":"uint32","name":"_nonce","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updaterManager","outputs":[{"internalType":"contract IUpdaterManager","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"notice":"Emitted when a new message is dispatched via Nomad"},"ImproperAttestation(address,bytes)":{"notice":"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state"},"NewUpdaterManager(address)":{"notice":"Emitted when the UpdaterManager contract is changed"},"UpdaterSlashed(address,address)":{"notice":"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)"}},"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"notice":"Dispatch the message to the destination domain \u0026 recipient"},"improperAttestation(bytes)":{"notice":"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation."},"root()":{"notice":"Calculates and returns tree's current root"},"setUpdater(address)":{"notice":"Set a new Updater"},"setUpdaterManager(address)":{"notice":"Set a new UpdaterManager contract"},"suggestUpdate()":{"notice":"Suggest an update for the Updater to sign and submit."}},"version":1},"developerDoc":{"events":{"Dispatch(bytes32,uint256,uint64,bytes,bytes)":{"params":{"destinationAndNonce":"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)","leafIndex":"Index of message's leaf in merkle tree","message":"Raw bytes of message","messageHash":"Hash of message; the leaf inserted to the Merkle tree for the message","tips":"Tips paid for the remote off-chain agents"}},"ImproperAttestation(address,bytes)":{"params":{"attestation":"Attestation data and signature","updater":"Updater who signed improper attestation"}},"NewUpdaterManager(address)":{"params":{"updaterManager":"The address of the new updaterManager"}},"UpdaterSlashed(address,address)":{"params":{"reporter":"The address of the entity that reported the updater misbehavior","updater":"The address of the updater"}}},"kind":"dev","methods":{"dispatch(uint32,bytes32,uint32,bytes,bytes)":{"details":"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.","params":{"_destinationDomain":"Domain of destination chain","_messageBody":"Raw bytes content of message","_recipientAddress":"Address of recipient on destination chain as bytes32"}},"improperAttestation(bytes)":{"details":"Reverts (and doesn't slash updater) if signature is invalid or update not current","params":{"_attestation":"Attestation data and signature"},"returns":{"_0":"TRUE if update was an Improper Attestation (implying Updater was slashed)"}},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"setUpdater(address)":{"details":"To be set when rotating Updater after Fraud","params":{"_updater":"the new Updater"}},"setUpdaterManager(address)":{"details":"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation","params":{"_updaterManager":"the new UpdaterManager contract"}},"suggestUpdate()":{"details":"If no messages have been sent, null bytes returned for both","returns":{"_nonce":"Current nonce","_root":"Current merkle root"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_localDomain\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"leafIndex\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destinationAndNonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"tips\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"}],\"name\":\"Dispatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"notary\",\"type\":\"address\"}],\"name\":\"DomainNotaryRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"guard\",\"type\":\"address\"}],\"name\":\"GuardRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"attestation\",\"type\":\"bytes\"}],\"name\":\"ImproperAttestation\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updaterManager\",\"type\":\"address\"}],\"name\":\"NewUpdaterManager\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"UpdaterSlashed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_MESSAGE_BODY_BYTES\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allGuards\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allNotaries\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destinationDomain\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_recipientAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_optimisticSeconds\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_tips\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_messageBody\",\"type\":\"bytes\"}],\"name\":\"dispatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGuard\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getNotary\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"guardsAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_attestation\",\"type\":\"bytes\"}],\"name\":\"improperAttestation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"notariesAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updater\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterManager\",\"type\":\"address\"}],\"name\":\"setUpdaterManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"enum Home.States\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"suggestUpdate\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"_nonce\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"_root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updaterManager\",\"outputs\":[{\"internalType\":\"contract IUpdaterManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"params\":{\"destinationAndNonce\":\"Destination and destination-specific nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\",\"leafIndex\":\"Index of message's leaf in merkle tree\",\"message\":\"Raw bytes of message\",\"messageHash\":\"Hash of message; the leaf inserted to the Merkle tree for the message\",\"tips\":\"Tips paid for the remote off-chain agents\"}},\"ImproperAttestation(address,bytes)\":{\"params\":{\"attestation\":\"Attestation data and signature\",\"updater\":\"Updater who signed improper attestation\"}},\"NewUpdaterManager(address)\":{\"params\":{\"updaterManager\":\"The address of the new updaterManager\"}},\"UpdaterSlashed(address,address)\":{\"params\":{\"reporter\":\"The address of the entity that reported the updater misbehavior\",\"updater\":\"The address of the updater\"}}},\"kind\":\"dev\",\"methods\":{\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"details\":\"Format the message, insert its hash into Merkle tree, enqueue the new Merkle root, and emit `Dispatch` event with message information.\",\"params\":{\"_destinationDomain\":\"Domain of destination chain\",\"_messageBody\":\"Raw bytes content of message\",\"_recipientAddress\":\"Address of recipient on destination chain as bytes32\"}},\"improperAttestation(bytes)\":{\"details\":\"Reverts (and doesn't slash updater) if signature is invalid or update not current\",\"params\":{\"_attestation\":\"Attestation data and signature\"},\"returns\":{\"_0\":\"TRUE if update was an Improper Attestation (implying Updater was slashed)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"setUpdater(address)\":{\"details\":\"To be set when rotating Updater after Fraud\",\"params\":{\"_updater\":\"the new Updater\"}},\"setUpdaterManager(address)\":{\"details\":\"Home(s) will initially be initialized using a trusted UpdaterManager contract; we will progressively decentralize by swapping the trusted contract with a new implementation that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\",\"params\":{\"_updaterManager\":\"the new UpdaterManager contract\"}},\"suggestUpdate()\":{\"details\":\"If no messages have been sent, null bytes returned for both\",\"returns\":{\"_nonce\":\"Current nonce\",\"_root\":\"Current merkle root\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"events\":{\"Dispatch(bytes32,uint256,uint64,bytes,bytes)\":{\"notice\":\"Emitted when a new message is dispatched via Nomad\"},\"ImproperAttestation(address,bytes)\":{\"notice\":\"Emitted when proof of an improper attestation is submitted, which sets the contract to FAILED state\"},\"NewUpdaterManager(address)\":{\"notice\":\"Emitted when the UpdaterManager contract is changed\"},\"UpdaterSlashed(address,address)\":{\"notice\":\"Emitted when the Updater is slashed (should be paired with ImproperUpdater or DoubleUpdate event)\"}},\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"dispatch(uint32,bytes32,uint32,bytes,bytes)\":{\"notice\":\"Dispatch the message to the destination domain \u0026 recipient\"},\"improperAttestation(bytes)\":{\"notice\":\"Check if an Attestation is an Improper Attestation; if so, slash the Updater and set the contract to FAILED state. An Improper Attestation is a (_nonce, _root) update that doesn't correspond with the historical state of Home contract. Either of those needs to be true: - _nonce is higher than current nonce (no root exists for this nonce) - _root is not equal to the historical root of _nonce This would mean that message(s) that were not truly dispatched on Home were falsely included in the signed root. An Improper Attestation will only be accepted as valid by the Replica If an Improper Attestation is attempted on Home, the Updater will be slashed immediately. If an Improper Attestation is submitted to the Replica, it should be relayed to the Home contract using this function in order to slash the Updater with an Improper Attestation.\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"},\"setUpdater(address)\":{\"notice\":\"Set a new Updater\"},\"setUpdaterManager(address)\":{\"notice\":\"Set a new UpdaterManager contract\"},\"suggestUpdate()\":{\"notice\":\"Suggest an update for the Updater to sign and submit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Home\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"MAX_MESSAGE_BODY_BYTES()":"522ae002","VERSION()":"ffa1ad74","allGuards()":"9fe03fa2","allNotaries()":"9817e315","count()":"06661abd","dispatch(uint32,bytes32,uint32,bytes,bytes)":"f7560e40","getGuard(uint256)":"629ddf69","getNotary(uint256)":"c07dc7f5","guardsAmount()":"246c2449","historicalRoots(uint256)":"7ea97f40","improperAttestation(bytes)":"0afe7f90","initialize(address)":"c4d66de8","localDomain()":"8d3638f4","nonce()":"affed0e0","notariesAmount()":"8e62e9ef","owner()":"8da5cb5b","renounceOwnership()":"715018a6","root()":"ebf0c717","setSystemMessenger(address)":"b7bc563e","setUpdater(address)":"9d54f419","setUpdaterManager(address)":"9776120e","state()":"c19d93fb","suggestUpdate()":"36e104de","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b","tree()":"fd54b228","updaterManager()":"9df6c8e1"}},"solidity/UpdaterManager.sol:ISystemMessenger":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"uint32","name":"_destDomain","type":"uint32"},{"internalType":"enum ISystemMessenger.SystemContracts","name":"_recipient","type":"uint8"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"sendSystemMessage","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"notice":"Send System Message to one of the System Contracts on origin chain"}},"version":1},"developerDoc":{"kind":"dev","methods":{"sendSystemMessage(uint32,uint8,bytes)":{"details":"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.","params":{"_destDomain":"Domain of destination chain","_payload":"Data for calling recipient on destination chain","_recipient":"System contract type of the recipient"}}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_destDomain\",\"type\":\"uint32\"},{\"internalType\":\"enum ISystemMessenger.SystemContracts\",\"name\":\"_recipient\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_payload\",\"type\":\"bytes\"}],\"name\":\"sendSystemMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"details\":\"Note that knowledge of recipient address is not required, routing will be done by SystemMessenger on destination chain.\",\"params\":{\"_destDomain\":\"Domain of destination chain\",\"_payload\":\"Data for calling recipient on destination chain\",\"_recipient\":\"System contract type of the recipient\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"sendSystemMessage(uint32,uint8,bytes)\":{\"notice\":\"Send System Message to one of the System Contracts on origin chain\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"ISystemMessenger\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"sendSystemMessage(uint32,uint8,bytes)":"0d1e27a7"}},"solidity/UpdaterManager.sol:IUpdaterManager":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"inputs":[{"internalType":"address payable","name":"_reporter","type":"address"}],"name":"slashUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"IUpdaterManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"slashUpdater(address)":"5b3c2cbf","updater()":"df034cd0"}},"solidity/UpdaterManager.sol:Initializable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"custom:oz-upgrades-unsafe-allow":"constructor constructor() { _disableInitializers(); } ``` ====","details":"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\"MyToken\", \"MTK\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\"MyToken\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```","events":{"Initialized(uint8)":{"details":"Triggered when the contract has been initialized or reinitialized."}},"kind":"dev","methods":{},"stateVariables":{"_initialized":{"custom:oz-retyped-from":"bool","details":"Indicates that the contract has been initialized."},"_initializing":{"details":"Indicates that the contract is in the process of being initialized."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"}],\"devdoc\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor constructor() { _disableInitializers(); } ``` ====\",\"details\":\"This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. The initialization functions use a version number. Once a version number is used, it is consumed and cannot be reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in case an upgrade adds a module that needs to be initialized. For example: [.hljs-theme-light.nopadding] ``` contract MyToken is ERC20Upgradeable { function initialize() initializer public { __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\"); } } contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { function initializeV2() reinitializer(2) public { __ERC20Permit_init(\\\"MyToken\\\"); } } ``` TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. [CAUTION] ==== Avoid leaving a contract uninitialized. An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: [.hljs-theme-light.nopadding] ```\",\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"_initialized\":{\"custom:oz-retyped-from\":\"bool\",\"details\":\"Indicates that the contract has been initialized.\"},\"_initializing\":{\"details\":\"Indicates that the contract is in the process of being initialized.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Initializable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:MerkleLib":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208c9e733f9ac0589d4e1d3269ad7a58e7124ea1bb40c5ed969a517b37a1cf0d0a64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208c9e733f9ac0589d4e1d3269ad7a58e7124ea1bb40c5ed969a517b37a1cf0d0a64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"69158:8018:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;69158:8018:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"69158:8018:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"MerkleLib\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:MerkleTreeManager":{"code":"0x608060405234801561001057600080fd5b506106f8806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220a5ab9978e9fd162d72901677ca68624f59d21c35b8982bd3d593e120c7e5016c64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806306661abd146100515780637ea97f4014610067578063ebf0c7171461007a578063fd54b22814610082575b600080fd5b6020545b60405190815260200160405180910390f35b61005561007536600461067a565b61008c565b6100556100ad565b6020546100559081565b6021818154811061009c57600080fd5b600091825260209091200154905081565b60006100b960006100be565b905090565b60006100d1826100cc6100d7565b610598565b92915050565b6100df61065b565b600081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb560208201527fb4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d3060408201527f21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba8560608201527fe58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a1934460808201527f0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d60a08201527f887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a196860c08201527fffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f8360e08201527f9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af6101008201527fcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e06101208201527ff9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a56101408201527ff8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf8926101608201527f3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c6101808201527fc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb6101a08201527f5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc6101c08201527fda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d26101e08201527f2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f6102008201527fe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a6102208201527f5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a06102408201527fb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa06102608201527fc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e26102808201527ff4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd96102a08201527f5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e3776102c08201527f4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee6526102e08201527fcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef6103008201527f0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d6103208201527fb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d06103408201527f838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e6103608201527f662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e6103808201527f388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea3226103a08201527f93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d7356103c08201527f8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a96103e082015290565b6020820154600090815b602081101561065357600182821c8116908190036105ff578582602081106105cc576105cc610693565b0154604080516020810192909252810185905260600160405160208183030381529060405280519060200120935061064a565b8385836020811061061257610612610693565b6020020151604051602001610631929190918252602082015260400190565b6040516020818303038152906040528051906020012093505b506001016105a2565b505092915050565b6040518061040001604052806020906020820280368337509192915050565b60006020828403121561068c57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220a5ab9978e9fd162d72901677ca68624f59d21c35b8982bd3d593e120c7e5016c64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"116275:968:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"116275:968:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116880:81;116944:10;;116880:81;;;160:25:1;;;148:2;133:18;116880:81:0;;;;;;;116424:32;;;;;;:::i;:::-;;:::i;116696:81::-;;;:::i;116392:26::-;;;;;;;116424:32;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116424:32:0;:::o;116696:81::-;116733:7;116759:11;:4;:9;:11::i;:::-;116752:18;;116696:81;:::o;71297:122::-;71354:7;71380:32;71392:5;71399:12;:10;:12::i;:::-;71380:11;:32::i;:::-;71373:39;71297:122;-1:-1:-1;;71297:122:0:o;71537:964::-;71582:34;;:::i;:::-;71641:3;71628:16;;71667:3;71628:10;71654;;:16;71693:3;71680:10;;;:16;71719:3;71706:10;;;:16;71745:3;71732:10;;;:16;71771:3;71758:10;;;:16;71797:3;71784:10;;;:16;71823:3;71810:10;;;:16;71849:3;71836:10;;;:16;71875:3;71862:10;;;:16;71902:4;71888:11;;;:18;71930:4;71916:11;;;:18;71958:4;71944:11;;;:18;71986:4;71972:11;;;:18;72014:4;72000:11;;;:18;72042:4;72028:11;;;:18;72070:4;72056:11;;;:18;72098:4;72084:11;;;:18;72126:4;72112:11;;;:18;72154:4;72140:11;;;:18;72182:4;72168:11;;;:18;72210:4;72196:11;;;:18;72238:4;72224:11;;;:18;72266:4;72252:11;;;:18;72294:4;72280:11;;;:18;72322:4;72308:11;;;:18;72350:4;72336:11;;;:18;72378:4;72364:11;;;:18;72406:4;72392:11;;;:18;72434:4;72420:11;;;:18;72462:4;72448:11;;;:18;72490:4;72476:11;;;:18;71628:7;71537:964::o;70641:589::-;70814:11;;;;70765:16;;;70836:388;69221:2;70856:1;:14;70836:388;;;70922:4;70907:11;;;70906:20;;;70944:12;;;70940:215;;71014:5;71027:1;71014:15;;;;;;;:::i;:::-;;;70997:43;;;;;;909:19:1;;;;944:12;;937:28;;;981:12;;70997:43:0;;;;;;;;;;;;70987:54;;;;;;70976:65;;70940:215;;;71118:8;71128:7;71136:1;71128:10;;;;;;;:::i;:::-;;;;;71101:38;;;;;;;;909:19:1;;;953:2;944:12;;937:28;990:2;981:12;;752:247;71101:38:0;;;;;;;;;;;;;71091:49;;;;;;71080:60;;70940:215;-1:-1:-1;71196:3:0;;70836:388;;;;70787:443;70641:589;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;196:180:1:-;255:6;308:2;296:9;287:7;283:23;279:32;276:52;;;324:1;321;314:12;276:52;-1:-1:-1;347:23:1;;196:180;-1:-1:-1;196:180:1:o;563:184::-;615:77;612:1;605:88;712:4;709:1;702:15;736:4;733:1;726:15","abiDefinition":[{"inputs":[],"name":"count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"historicalRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tree","outputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{"count()":{"notice":"Returns the number of inserted leaves in the tree (current index)"},"root()":{"notice":"Calculates and returns tree's current root"}},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"count\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"historicalRoots\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"root\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tree\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"count()\":{\"notice\":\"Returns the number of inserted leaves in the tree (current index)\"},\"root()\":{\"notice\":\"Calculates and returns tree's current root\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"MerkleTreeManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"count()":"06661abd","historicalRoots(uint256)":"7ea97f40","root()":"ebf0c717","tree()":"fd54b228"}},"solidity/UpdaterManager.sol:Message":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205ae5747286052a50a840c40a36debae4290685b79799018ad5492a14cd0d700164736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205ae5747286052a50a840c40a36debae4290685b79799018ad5492a14cd0d700164736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"81599:4971:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;81599:4971:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"81599:4971:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"HEADER_OFFSET":{"details":"This value reflects the header offset in the latest message version"},"MESSAGE_VERSION":{"details":"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped."},"TWO_BYTES":{"details":"How much bytes is used for storing the version, or a single offset value"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"HEADER_OFFSET\":{\"details\":\"This value reflects the header offset in the latest message version\"},\"MESSAGE_VERSION\":{\"details\":\"This is only updated if the whole message structure is changed, i.e. if a new part is added. If already existing part is changed, the message version does not get bumped.\"},\"TWO_BYTES\":{\"details\":\"How much bytes is used for storing the version, or a single offset value\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Message\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Ownable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"constructor":{"details":"Initializes the contract setting the deployer as the initial owner."},"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"constructor\":{\"details\":\"Initializes the contract setting the deployer as the initial owner.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Ownable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/UpdaterManager.sol:OwnableUpgradeable":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner."},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"stateVariables":{"__gap":{"details":"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"stateVariables\":{\"__gap\":{\"details\":\"This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain. See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"OwnableUpgradeable\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"owner()":"8da5cb5b","renounceOwnership()":"715018a6","transferOwnership(address)":"f2fde38b"}},"solidity/UpdaterManager.sol:Strings":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e8344ff379070d013a936b22519238d053b96dac95b78d47146409ed6d790b4a64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220e8344ff379070d013a936b22519238d053b96dac95b78d47146409ed6d790b4a64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"35793:1885:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;35793:1885:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"35793:1885:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"details":"String operations.","kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"details\":\"String operations.\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Strings\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:SystemContract":{"code":"0x","runtime-code":"0x","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"","srcMapRuntime":"","abiDefinition":[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISystemMessenger","name":"_systemMessenger","type":"address"}],"name":"setSystemMessenger","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"systemMessenger","outputs":[{"internalType":"contract ISystemMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op"},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"localDomain\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"_systemMessenger\",\"type\":\"address\"}],\"name\":\"setSystemMessenger\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"systemMessenger\",\"outputs\":[{\"internalType\":\"contract ISystemMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Should be impossible to renounce ownership; we override OpenZeppelin OwnableUpgradeable's implementation of renounceOwnership to make it a no-op\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"SystemContract\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"localDomain()":"8d3638f4","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setSystemMessenger(address)":"b7bc563e","systemMessenger()":"ccbdf9c9","transferOwnership(address)":"f2fde38b"}},"solidity/UpdaterManager.sol:SystemMessage":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122064cd8c626afbf5334bd6d2c4c9a698cd7f253d64ccad6b7ea3294f4c749db02f64736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122064cd8c626afbf5334bd6d2c4c9a698cd7f253d64ccad6b7ea3294f4c749db02f64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"89573:4227:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;89573:4227:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"89573:4227:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_BODY":{"details":"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes"},"OFFSET_CALL_PAYLOAD":{"details":"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes"},"SYSTEM_SENDER":{"details":"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_BODY\":{\"details\":\"SystemMessage memory layout [000 .. 001): messageType uint8 1 bytes [001 .. END]: messageBody bytes ? bytes\"},\"OFFSET_CALL_PAYLOAD\":{\"details\":\"SystemMessageType.Call memory layout [000 .. 001): recipient uint8 1 bytes [001 .. END]: payload bytes ? bytes\"},\"SYSTEM_SENDER\":{\"details\":\"Custom address, used for receiving and sending system messages. Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address. ReplicaManager is supposed to reroute messages for this address to SystemMessenger. Note: all bits except for lower 20 bytes are set to 1. Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"SystemMessage\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:Tips":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d07e57f721e4163786684280338d56a69cdc5b67a4bc383ddc24c0064b7b8b2664736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d07e57f721e4163786684280338d56a69cdc5b67a4bc383ddc24c0064b7b8b2664736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"86572:2999:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;86572:2999:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"86572:2999:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"stateVariables":{"OFFSET_UPDATER":{"details":"Tips memory layout [000 .. 002): version uint16\t 2 bytes [002 .. 014): updaterTip uint96\t12 bytes [014 .. 026): relayerTip uint96\t12 bytes [026 .. 038): proverTip uint96\t12 bytes [038 .. 050): processorTip uint96\t12 bytes"}},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"OFFSET_UPDATER\":{\"details\":\"Tips memory layout [000 .. 002): version uint16\\t 2 bytes [002 .. 014): updaterTip uint96\\t12 bytes [014 .. 026): relayerTip uint96\\t12 bytes [026 .. 038): proverTip uint96\\t12 bytes [038 .. 050): processorTip uint96\\t12 bytes\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Tips\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:TypeCasts":{"code":"0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209a36b1ab0276d65052fa22a7df87ebbfa5bab351f13482975564e8f1eced2f2864736f6c634300080d0033","runtime-code":"0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212209a36b1ab0276d65052fa22a7df87ebbfa5bab351f13482975564e8f1eced2f2864736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"77182:1110:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;77182:1110:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"77182:1110:0:-:0;;;;;;;;","abiDefinition":[],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"TypeCasts\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{}},"solidity/UpdaterManager.sol:TypedMemView":{"code":"0x60c9610038600b82828239805160001a607314602b57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220fc0648112c9392b6186c78f34911f5cd0662b794e868bd97e8300d36afbfb81464736f6c634300080d0033","runtime-code":"0x730000000000000000000000000000000000000000301460806040526004361060335760003560e01c8063f26be3fc146038575b600080fd5b605e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000081565b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116815260200160405180910390f3fea2646970667358221220fc0648112c9392b6186c78f34911f5cd0662b794e868bd97e8300d36afbfb81464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"239:32242:0:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;239:32242:0;;;;;;;;;;;;;;;;;","srcMapRuntime":"239:32242:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;2752:94;;;;;;;;198:66:1;186:79;;;168:98;;156:2;141:18;2752:94:0;;;;;;","abiDefinition":[{"inputs":[],"name":"NULL","outputs":[{"internalType":"bytes29","name":"","type":"bytes29"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NULL\",\"outputs\":[{\"internalType\":\"bytes29\",\"name\":\"\",\"type\":\"bytes29\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"TypedMemView\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"NULL()":"f26be3fc"}},"solidity/UpdaterManager.sol:UpdaterManager":{"code":"0x60806040526040516108a83803806108a8833981016040819052610022916100a0565b61002b33610050565b600280546001600160a01b0319166001600160a01b03929092169190911790556100d0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156100b257600080fd5b81516001600160a01b03811681146100c957600080fd5b9392505050565b6107c9806100df6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80639d54f4191161005b5780639d54f419146101005780639fa92f9d14610113578063df034cd014610133578063f2fde38b1461015157600080fd5b80635b3c2cbf1461008d5780636ef0f37f146100a2578063715018a6146100b55780638da5cb5b146100bd575b600080fd5b6100a061009b36600461076f565b610164565b005b6100a06100b036600461076f565b610237565b6100a06103a9565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100a061010e36600461076f565b61042c565b6001546100d79073ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff166100d7565b6100a061015f36600461076f565b6105a8565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f21686f6d6500000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60405173ffffffffffffffffffffffffffffffffffffffff821681527f4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81163b610336576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f21636f6e747261637420686f6d6500000000000000000000000000000000000060448201526064016101e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de219060200161022c565b60005473ffffffffffffffffffffffffffffffffffffffff16331461042a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556001546040517f9d54f419000000000000000000000000000000000000000000000000000000008152600481019290925290911690639d54f41990602401600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681527f9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c329250602001905061022c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81166106cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101e1565b6106d5816106d8565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106d557600080fd5b60006020828403121561078157600080fd5b813561078c8161074d565b939250505056fea2646970667358221220333c3411f3fb78827ee9c4ed7dac81c513db0b8e6d2dab91e42599d68c45683c64736f6c634300080d0033","runtime-code":"0x608060405234801561001057600080fd5b50600436106100885760003560e01c80639d54f4191161005b5780639d54f419146101005780639fa92f9d14610113578063df034cd014610133578063f2fde38b1461015157600080fd5b80635b3c2cbf1461008d5780636ef0f37f146100a2578063715018a6146100b55780638da5cb5b146100bd575b600080fd5b6100a061009b36600461076f565b610164565b005b6100a06100b036600461076f565b610237565b6100a06103a9565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6100a061010e36600461076f565b61042c565b6001546100d79073ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff166100d7565b6100a061015f36600461076f565b6105a8565b60015473ffffffffffffffffffffffffffffffffffffffff1633146101ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f21686f6d6500000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b60405173ffffffffffffffffffffffffffffffffffffffff821681527f4180932f5f5f11458bcd408e42c54626987799e7c4c89f40f484fefdfdfff14f906020015b60405180910390a150565b60005473ffffffffffffffffffffffffffffffffffffffff1633146102b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81163b610336576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f21636f6e747261637420686f6d6500000000000000000000000000000000000060448201526064016101e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa6c230e5615262e310dcb42eaf014e813e5d8580abf5b00d2186ca8e9833de219060200161022c565b60005473ffffffffffffffffffffffffffffffffffffffff16331461042a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092556001546040517f9d54f419000000000000000000000000000000000000000000000000000000008152600481019290925290911690639d54f41990602401600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff841681527f9e5f57e4ee5f9eeac3131028d48f19d80820ce6fa93c4c66cc82a3e2b9837c329250602001905061022c565b60005473ffffffffffffffffffffffffffffffffffffffff163314610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016101e1565b73ffffffffffffffffffffffffffffffffffffffff81166106cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016101e1565b6106d5816106d8565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106d557600080fd5b60006020828403121561078157600080fd5b813561078c8161074d565b939250505056fea2646970667358221220333c3411f3fb78827ee9c4ed7dac81c513db0b8e6d2dab91e42599d68c45683c64736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"140580:2751:0:-:0;;;141599:98;;;;;;;;;;;;;;;;;;:::i;:::-;138756:32;138348:10;138756:18;:32::i;:::-;141664:8:::1;:26:::0;;-1:-1:-1;;;;;;141664:26:0::1;-1:-1:-1::0;;;;;141664:26:0;;;::::1;::::0;;;::::1;::::0;;140580:2751;;140105:187;140178:16;140197:6;;-1:-1:-1;;;;;140213:17:0;;;-1:-1:-1;;;;;;140213:17:0;;;;;;140245:40;;140197:6;;;;;;;140245:40;;140178:16;140245:40;140168:124;140105:187;:::o;14:290:1:-;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;179:16;;-1:-1:-1;;;;;224:31:1;;214:42;;204:70;;270:1;267;260:12;204:70;293:5;14:290;-1:-1:-1;;;14:290:1:o;:::-;140580:2751:0;;;;;;","srcMapRuntime":"140580:2751:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;142750:120;;;;;;:::i;:::-;;:::i;:::-;;141930:172;;;;;;:::i;:::-;;:::i;143245:84::-;;;:::i;138871:85::-;138917:7;138943:6;;;138871:85;;;885:42:1;873:55;;;855:74;;843:2;828:18;138871:85:0;;;;;;;142276:197;;;;;;:::i;:::-;;:::i;140719:19::-;;;;;;;;;142973:92;143050:8;;;;142973:92;;139753:198;;;;;;:::i;:::-;;:::i;142750:120::-;141515:4;;;;141501:10;:18;141493:36;;;;;;;1142:2:1;141493:36:0;;;1124:21:1;1181:1;1161:18;;;1154:29;1219:7;1199:18;;;1192:35;1244:18;;141493:36:0;;;;;;;;;142841:22:::1;::::0;885:42:1;873:55;;855:74;;142841:22:0::1;::::0;843:2:1;828:18;142841:22:0::1;;;;;;;;142750:120:::0;:::o;141930:172::-;138917:7;138943:6;139083:23;138943:6;138348:10;139083:23;139075:68;;;;;;;1714:2:1;139075:68:0;;;1696:21:1;;;1733:18;;;1726:30;1792:34;1772:18;;;1765:62;1844:18;;139075:68:0;1512:356:1;139075:68:0;118516:19;;;;141991:52:::1;;;::::0;::::1;::::0;;2075:2:1;141991:52:0::1;::::0;::::1;2057:21:1::0;2114:2;2094:18;;;2087:30;2153:16;2133:18;;;2126:44;2187:18;;141991:52:0::1;1873:338:1::0;141991:52:0::1;142053:4;:12:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;142081:14:::1;::::0;855:74:1;;;142081:14:0::1;::::0;843:2:1;828:18;142081:14:0::1;709:226:1::0;143245:84:0;138917:7;138943:6;139083:23;138943:6;138348:10;139083:23;139075:68;;;;;;;1714:2:1;139075:68:0;;;1696:21:1;;;1733:18;;;1726:30;1792:34;1772:18;;;1765:62;1844:18;;139075:68:0;1512:356:1;139075:68:0;143245:84::o;142276:197::-;138917:7;138943:6;139083:23;138943:6;138348:10;139083:23;139075:68;;;;;;;1714:2:1;139075:68:0;;;1696:21:1;;;1733:18;;;1726:30;1792:34;1772:18;;;1765:62;1844:18;;139075:68:0;1512:356:1;139075:68:0;142350:8:::1;:26:::0;;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;142391:4:0;142386:38:::1;::::0;;;;::::1;::::0;::::1;855:74:1::0;;;;142391:4:0;;::::1;::::0;142386:21:::1;::::0;828:18:1;;142386:38:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;142439:27:0::1;::::0;885:42:1;873:55;;855:74;;142439:27:0::1;::::0;-1:-1:-1;843:2:1;828:18;;-1:-1:-1;142439:27:0::1;709:226:1::0;139753:198:0;138917:7;138943:6;139083:23;138943:6;138348:10;139083:23;139075:68;;;;;;;1714:2:1;139075:68:0;;;1696:21:1;;;1733:18;;;1726:30;1792:34;1772:18;;;1765:62;1844:18;;139075:68:0;1512:356:1;139075:68:0;139841:22:::1;::::0;::::1;139833:73;;;::::0;::::1;::::0;;2418:2:1;139833:73:0::1;::::0;::::1;2400:21:1::0;2457:2;2437:18;;;2430:30;2496:34;2476:18;;;2469:62;2567:8;2547:18;;;2540:36;2593:19;;139833:73:0::1;2216:402:1::0;139833:73:0::1;139916:28;139935:8;139916:18;:28::i;:::-;139753:198:::0;:::o;140105:187::-;140178:16;140197:6;;;140213:17;;;;;;;;;;140245:40;;140197:6;;;;;;;140245:40;;140178:16;140245:40;140168:124;140105:187;:::o;14:162:1:-;108:42;101:5;97:54;90:5;87:65;77:93;;166:1;163;156:12;181:263;248:6;301:2;289:9;280:7;276:23;272:32;269:52;;;317:1;314;307:12;269:52;356:9;343:23;375:39;408:5;375:39;:::i;:::-;433:5;181:263;-1:-1:-1;;;181:263:1:o","abiDefinition":[{"inputs":[{"internalType":"address","name":"_updaterAddress","type":"address"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"reporter","type":"address"}],"name":"FakeSlashed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"home","type":"address"}],"name":"NewHome","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"updater","type":"address"}],"name":"NewUpdater","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"home","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_home","type":"address"}],"name":"setHome","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_updaterAddress","type":"address"}],"name":"setUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_reporter","type":"address"}],"name":"slashUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"userDoc":{"events":{"FakeSlashed(address)":{"notice":"Emitted when slashUpdater is called"},"NewHome(address)":{"notice":"Emitted when a new home is set"},"NewUpdater(address)":{"notice":"Emitted when a new updater is set"}},"kind":"user","methods":{"setHome(address)":{"notice":"Set the address of the a new home contract"},"setUpdater(address)":{"notice":"Set the address of a new updater"},"slashUpdater(address)":{"notice":"Slashes the updater"},"updater()":{"notice":"Get address of current updater"}},"notice":"MVP / centralized version of contract that will manage Updater bonding, slashing, selection and rotation","version":1},"developerDoc":{"author":"Illusory Systems Inc.","events":{"NewHome(address)":{"params":{"home":"The address of the new home contract"}},"NewUpdater(address)":{"params":{"updater":"The address of the new updater"}}},"kind":"dev","methods":{"owner()":{"details":"Returns the address of the current owner."},"renounceOwnership()":{"details":"should be impossible to renounce ownership; we override OpenZeppelin Ownable implementation of renounceOwnership to make it a no-op"},"setHome(address)":{"details":"only callable by trusted owner","params":{"_home":"The address of the new home contract"}},"setUpdater(address)":{"details":"only callable by trusted owner","params":{"_updaterAddress":"The address of the new updater"}},"slashUpdater(address)":{"details":"Currently does nothing, functionality will be implemented later when updater bonding and rotation are also implemented","params":{"_reporter":"The address of the entity that reported the updater fraud"}},"transferOwnership(address)":{"details":"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."},"updater()":{"returns":{"_0":"the updater address"}}},"title":"UpdaterManager","version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterAddress\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"reporter\",\"type\":\"address\"}],\"name\":\"FakeSlashed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"home\",\"type\":\"address\"}],\"name\":\"NewHome\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"}],\"name\":\"NewUpdater\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"home\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_home\",\"type\":\"address\"}],\"name\":\"setHome\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_updaterAddress\",\"type\":\"address\"}],\"name\":\"setUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"_reporter\",\"type\":\"address\"}],\"name\":\"slashUpdater\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updater\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Illusory Systems Inc.\",\"events\":{\"NewHome(address)\":{\"params\":{\"home\":\"The address of the new home contract\"}},\"NewUpdater(address)\":{\"params\":{\"updater\":\"The address of the new updater\"}}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"should be impossible to renounce ownership; we override OpenZeppelin Ownable implementation of renounceOwnership to make it a no-op\"},\"setHome(address)\":{\"details\":\"only callable by trusted owner\",\"params\":{\"_home\":\"The address of the new home contract\"}},\"setUpdater(address)\":{\"details\":\"only callable by trusted owner\",\"params\":{\"_updaterAddress\":\"The address of the new updater\"}},\"slashUpdater(address)\":{\"details\":\"Currently does nothing, functionality will be implemented later when updater bonding and rotation are also implemented\",\"params\":{\"_reporter\":\"The address of the entity that reported the updater fraud\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"updater()\":{\"returns\":{\"_0\":\"the updater address\"}}},\"title\":\"UpdaterManager\",\"version\":1},\"userdoc\":{\"events\":{\"FakeSlashed(address)\":{\"notice\":\"Emitted when slashUpdater is called\"},\"NewHome(address)\":{\"notice\":\"Emitted when a new home is set\"},\"NewUpdater(address)\":{\"notice\":\"Emitted when a new updater is set\"}},\"kind\":\"user\",\"methods\":{\"setHome(address)\":{\"notice\":\"Set the address of the a new home contract\"},\"setUpdater(address)\":{\"notice\":\"Set the address of a new updater\"},\"slashUpdater(address)\":{\"notice\":\"Slashes the updater\"},\"updater()\":{\"notice\":\"Get address of current updater\"}},\"notice\":\"MVP / centralized version of contract that will manage Updater bonding, slashing, selection and rotation\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"UpdaterManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"home()":"9fa92f9d","owner()":"8da5cb5b","renounceOwnership()":"715018a6","setHome(address)":"6ef0f37f","setUpdater(address)":"9d54f419","slashUpdater(address)":"5b3c2cbf","transferOwnership(address)":"f2fde38b","updater()":"df034cd0"}},"solidity/UpdaterManager.sol:Version0":{"code":"0x6080604052348015600f57600080fd5b5060808061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208e7a175bf2a5d2eca4f04a20dce3075bc55167057de74d26eba65775fcc685b464736f6c634300080d0033","runtime-code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063ffa1ad7414602d575b600080fd5b6034600081565b60405160ff909116815260200160405180910390f3fea26469706673582212208e7a175bf2a5d2eca4f04a20dce3075bc55167057de74d26eba65775fcc685b464736f6c634300080d0033","info":{"source":"pragma solidity 0.8.13;\n\n\ninterface IUpdaterManager {\n function slashUpdater(address payable _reporter) external;\n\n function updater() external view returns (address);\n}\n\ncontract Version0 {\n uint8 public constant VERSION = 0;\n}\n\nlibrary TypedMemView {\n // Why does this exist?\n // the solidity `bytes memory` type has a few weaknesses.\n // 1. You can't index ranges effectively\n // 2. You can't slice without copying\n // 3. The underlying data may represent any type\n // 4. Solidity never deallocates memory, and memory costs grow\n // superlinearly\n\n // By using a memory view instead of a `bytes memory` we get the following\n // advantages:\n // 1. Slices are done on the stack, by manipulating the pointer\n // 2. We can index arbitrary ranges and quickly convert them to stack types\n // 3. We can insert type info into the pointer, and typecheck at runtime\n\n // This makes `TypedMemView` a useful tool for efficient zero-copy\n // algorithms.\n\n // Why bytes29?\n // We want to avoid confusion between views, digests, and other common\n // types so we chose a large and uncommonly used odd number of bytes\n //\n // Note that while bytes are left-aligned in a word, integers and addresses\n // are right-aligned. This means when working in assembly we have to\n // account for the 3 unused bytes on the righthand side\n //\n // First 5 bytes are a type flag.\n // - ff_ffff_fffe is reserved for unknown type.\n // - ff_ffff_ffff is reserved for invalid types/errors.\n // next 12 are memory address\n // next 12 are len\n // bottom 3 bytes are empty\n\n // Assumptions:\n // - non-modification of memory.\n // - No Solidity updates\n // - - wrt free mem point\n // - - wrt bytes representation in memory\n // - - wrt memory addressing in general\n\n // Usage:\n // - create type constants\n // - use `assertType` for runtime type assertions\n // - - unfortunately we can't do this at compile time yet :(\n // - recommended: implement modifiers that perform type checking\n // - - e.g.\n // - - `uint40 constant MY_TYPE = 3;`\n // - - ` modifer onlyMyType(bytes29 myView) { myView.assertType(MY_TYPE); }`\n // - instantiate a typed view from a bytearray using `ref`\n // - use `index` to inspect the contents of the view\n // - use `slice` to create smaller views into the same memory\n // - - `slice` can increase the offset\n // - - `slice can decrease the length`\n // - - must specify the output type of `slice`\n // - - `slice` will return a null view if you try to overrun\n // - - make sure to explicitly check for this with `notNull` or `assertType`\n // - use `equal` for typed comparisons.\n\n // The null view\n bytes29 public constant NULL = hex\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\";\n uint256 constant LOW_12_MASK = 0xffffffffffffffffffffffff;\n uint8 constant TWELVE_BYTES = 96;\n\n /**\n * @notice Returns the encoded hex character that represents the lower 4 bits of the argument.\n * @param _b The byte\n * @return char - The encoded hex character\n */\n function nibbleHex(uint8 _b) internal pure returns (uint8 char) {\n // This can probably be done more efficiently, but it's only in error\n // paths, so we don't really care :)\n uint8 _nibble = _b | 0xf0; // set top 4, keep bottom 4\n if (_nibble == 0xf0) {\n return 0x30;\n } // 0\n if (_nibble == 0xf1) {\n return 0x31;\n } // 1\n if (_nibble == 0xf2) {\n return 0x32;\n } // 2\n if (_nibble == 0xf3) {\n return 0x33;\n } // 3\n if (_nibble == 0xf4) {\n return 0x34;\n } // 4\n if (_nibble == 0xf5) {\n return 0x35;\n } // 5\n if (_nibble == 0xf6) {\n return 0x36;\n } // 6\n if (_nibble == 0xf7) {\n return 0x37;\n } // 7\n if (_nibble == 0xf8) {\n return 0x38;\n } // 8\n if (_nibble == 0xf9) {\n return 0x39;\n } // 9\n if (_nibble == 0xfa) {\n return 0x61;\n } // a\n if (_nibble == 0xfb) {\n return 0x62;\n } // b\n if (_nibble == 0xfc) {\n return 0x63;\n } // c\n if (_nibble == 0xfd) {\n return 0x64;\n } // d\n if (_nibble == 0xfe) {\n return 0x65;\n } // e\n if (_nibble == 0xff) {\n return 0x66;\n } // f\n }\n\n /**\n * @notice Returns a uint16 containing the hex-encoded byte.\n * @param _b The byte\n * @return encoded - The hex-encoded byte\n */\n function byteHex(uint8 _b) internal pure returns (uint16 encoded) {\n encoded |= nibbleHex(_b \u003e\u003e 4); // top 4 bits\n encoded \u003c\u003c= 8;\n encoded |= nibbleHex(_b); // lower 4 bits\n }\n\n /**\n * @notice Encodes the uint256 to hex. `first` contains the encoded top 16 bytes.\n * `second` contains the encoded lower 16 bytes.\n *\n * @param _b The 32 bytes as uint256\n * @return first - The top 16 bytes\n * @return second - The bottom 16 bytes\n */\n function encodeHex(uint256 _b) internal pure returns (uint256 first, uint256 second) {\n for (uint8 i = 31; i \u003e 15; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n first |= byteHex(_byte);\n if (i != 16) {\n first \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n\n // abusing underflow here =_=\n for (uint8 i = 15; i \u003c 255; ) {\n uint8 _byte = uint8(_b \u003e\u003e (i * 8));\n second |= byteHex(_byte);\n if (i != 0) {\n second \u003c\u003c= 16;\n }\n unchecked {\n i -= 1;\n }\n }\n }\n\n /**\n * @notice Changes the endianness of a uint256.\n * @dev https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel\n * @param _b The unsigned integer to reverse\n * @return v - The reversed value\n */\n function reverseUint256(uint256 _b) internal pure returns (uint256 v) {\n v = _b;\n\n // swap bytes\n v =\n ((v \u003e\u003e 8) \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) |\n ((v \u0026 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) \u003c\u003c 8);\n // swap 2-byte long pairs\n v =\n ((v \u003e\u003e 16) \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) |\n ((v \u0026 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) \u003c\u003c 16);\n // swap 4-byte long pairs\n v =\n ((v \u003e\u003e 32) \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) |\n ((v \u0026 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) \u003c\u003c 32);\n // swap 8-byte long pairs\n v =\n ((v \u003e\u003e 64) \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) |\n ((v \u0026 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) \u003c\u003c 64);\n // swap 16-byte long pairs\n v = (v \u003e\u003e 128) | (v \u003c\u003c 128);\n }\n\n /**\n * @notice Create a mask with the highest `_len` bits set.\n * @param _len The length\n * @return mask - The mask\n */\n function leftMask(uint8 _len) private pure returns (uint256 mask) {\n // ugly. redo without assembly?\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mask := sar(\n sub(_len, 1),\n 0x8000000000000000000000000000000000000000000000000000000000000000\n )\n }\n }\n\n /**\n * @notice Return the null view.\n * @return bytes29 - The null view\n */\n function nullView() internal pure returns (bytes29) {\n return NULL;\n }\n\n /**\n * @notice Check if the view is null.\n * @return bool - True if the view is null\n */\n function isNull(bytes29 memView) internal pure returns (bool) {\n return memView == NULL;\n }\n\n /**\n * @notice Check if the view is not null.\n * @return bool - True if the view is not null\n */\n function notNull(bytes29 memView) internal pure returns (bool) {\n return !isNull(memView);\n }\n\n /**\n * @notice Check if the view is of a valid type and points to a valid location\n * in memory.\n * @dev We perform this check by examining solidity's unallocated memory\n * pointer and ensuring that the view's upper bound is less than that.\n * @param memView The view\n * @return ret - True if the view is valid\n */\n function isValid(bytes29 memView) internal pure returns (bool ret) {\n if (typeOf(memView) == 0xffffffffff) {\n return false;\n }\n uint256 _end = end(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ret := not(gt(_end, mload(0x40)))\n }\n }\n\n /**\n * @notice Require that a typed memory view be valid.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @return bytes29 - The validated view\n */\n function assertValid(bytes29 memView) internal pure returns (bytes29) {\n require(isValid(memView), \"Validity assertion failed\");\n return memView;\n }\n\n /**\n * @notice Return true if the memview is of the expected type. Otherwise false.\n * @param memView The view\n * @param _expected The expected type\n * @return bool - True if the memview is of the expected type\n */\n function isType(bytes29 memView, uint40 _expected) internal pure returns (bool) {\n return typeOf(memView) == _expected;\n }\n\n /**\n * @notice Require that a typed memory view has a specific type.\n * @dev Returns the view for easy chaining.\n * @param memView The view\n * @param _expected The expected type\n * @return bytes29 - The view with validated type\n */\n function assertType(bytes29 memView, uint40 _expected) internal pure returns (bytes29) {\n if (!isType(memView, _expected)) {\n (, uint256 g) = encodeHex(uint256(typeOf(memView)));\n (, uint256 e) = encodeHex(uint256(_expected));\n string memory err = string(\n abi.encodePacked(\n \"Type assertion failed. Got 0x\",\n uint80(g),\n \". Expected 0x\",\n uint80(e)\n )\n );\n revert(err);\n }\n return memView;\n }\n\n /**\n * @notice Return an identical view with a different type.\n * @param memView The view\n * @param _newType The new type\n * @return newView - The new view with the specified type\n */\n function castTo(bytes29 memView, uint40 _newType) internal pure returns (bytes29 newView) {\n // then | in the new type\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // shift off the top 5 bytes\n newView := or(newView, shr(40, shl(40, memView)))\n newView := or(newView, shl(216, _newType))\n }\n }\n\n /**\n * @notice Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Unsafe raw pointer construction. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function unsafeBuildUnchecked(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) private pure returns (bytes29 newView) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n newView := shl(96, or(newView, _type)) // insert type\n newView := shl(96, or(newView, _loc)) // insert loc\n newView := shl(24, or(newView, _len)) // empty bottom 3 bytes\n }\n }\n\n /**\n * @notice Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @dev Instantiate a new memory view. This should generally not be called\n * directly. Prefer `ref` wherever possible.\n * @param _type The type\n * @param _loc The memory address\n * @param _len The length\n * @return newView - The new view with the specified type, location and length\n */\n function build(\n uint256 _type,\n uint256 _loc,\n uint256 _len\n ) internal pure returns (bytes29 newView) {\n uint256 _end = _loc + _len;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n if gt(_end, mload(0x40)) {\n _end := 0\n }\n }\n if (_end == 0) {\n return NULL;\n }\n newView = unsafeBuildUnchecked(_type, _loc, _len);\n }\n\n /**\n * @notice Instantiate a memory view from a byte array.\n * @dev Note that due to Solidity memory representation, it is not possible to\n * implement a deref, as the `bytes` type stores its len in memory.\n * @param arr The byte array\n * @param newType The type\n * @return bytes29 - The memory view\n */\n function ref(bytes memory arr, uint40 newType) internal pure returns (bytes29) {\n uint256 _len = arr.length;\n\n uint256 _loc;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _loc := add(arr, 0x20) // our view is of the data, not the struct\n }\n\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Return the associated type information.\n * @param memView The memory view\n * @return _type - The type associated with the view\n */\n function typeOf(bytes29 memView) internal pure returns (uint40 _type) {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 216 == 256 - 40\n _type := shr(216, memView) // shift out lower 24 bytes\n }\n }\n\n /**\n * @notice Optimized type comparison. Checks that the 5-byte type flag is equal.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the 5-byte type flag is equal\n */\n function sameType(bytes29 left, bytes29 right) internal pure returns (bool) {\n return (left ^ right) \u003e\u003e (2 * TWELVE_BYTES) == 0;\n }\n\n /**\n * @notice Return the memory address of the underlying bytes.\n * @param memView The view\n * @return _loc - The memory address\n */\n function loc(bytes29 memView) internal pure returns (uint96 _loc) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // 120 bits = 12 bytes (the encoded loc) + 3 bytes (empty low space)\n _loc := and(shr(120, memView), _mask)\n }\n }\n\n /**\n * @notice The number of memory words this memory view occupies, rounded up.\n * @param memView The view\n * @return uint256 - The number of memory words\n */\n function words(bytes29 memView) internal pure returns (uint256) {\n return (uint256(len(memView)) + 32) / 32;\n }\n\n /**\n * @notice The in-memory footprint of a fresh copy of the view.\n * @param memView The view\n * @return uint256 - The in-memory footprint of a fresh copy of the view.\n */\n function footprint(bytes29 memView) internal pure returns (uint256) {\n return words(memView) * 32;\n }\n\n /**\n * @notice The number of bytes of the view.\n * @param memView The view\n * @return _len - The length of the view\n */\n function len(bytes29 memView) internal pure returns (uint96 _len) {\n uint256 _mask = LOW_12_MASK; // assembly can't use globals\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n _len := and(shr(24, memView), _mask)\n }\n }\n\n /**\n * @notice Returns the endpoint of `memView`.\n * @param memView The view\n * @return uint256 - The endpoint of `memView`\n */\n function end(bytes29 memView) internal pure returns (uint256) {\n unchecked {\n return loc(memView) + len(memView);\n }\n }\n\n /**\n * @notice Safe slicing without memory modification.\n * @param memView The view\n * @param _index The start index\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function slice(\n bytes29 memView,\n uint256 _index,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n uint256 _loc = loc(memView);\n\n // Ensure it doesn't overrun the view\n if (_loc + _index + _len \u003e end(memView)) {\n return NULL;\n }\n\n _loc = _loc + _index;\n return build(newType, _loc, _len);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the first `_len` bytes.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function prefix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, 0, _len, newType);\n }\n\n /**\n * @notice Shortcut to `slice`. Gets a view representing the last `_len` byte.\n * @param memView The view\n * @param _len The length\n * @param newType The new type\n * @return bytes29 - The new view\n */\n function postfix(\n bytes29 memView,\n uint256 _len,\n uint40 newType\n ) internal pure returns (bytes29) {\n return slice(memView, uint256(len(memView)) - _len, _len, newType);\n }\n\n /**\n * @notice Construct an error message for an indexing overrun.\n * @param _loc The memory address\n * @param _len The length\n * @param _index The index\n * @param _slice The slice where the overrun occurred\n * @return err - The err\n */\n function indexErrOverrun(\n uint256 _loc,\n uint256 _len,\n uint256 _index,\n uint256 _slice\n ) internal pure returns (string memory err) {\n (, uint256 a) = encodeHex(_loc);\n (, uint256 b) = encodeHex(_len);\n (, uint256 c) = encodeHex(_index);\n (, uint256 d) = encodeHex(_slice);\n err = string(\n abi.encodePacked(\n \"TypedMemView/index - Overran the view. Slice is at 0x\",\n uint48(a),\n \" with length 0x\",\n uint48(b),\n \". Attempted to index at offset 0x\",\n uint48(c),\n \" with length 0x\",\n uint48(d),\n \".\"\n )\n );\n }\n\n /**\n * @notice Load up to 32 bytes from the view onto the stack.\n * @dev Returns a bytes32 with only the `_bytes` highest bytes set.\n * This can be immediately cast to a smaller fixed-length byte array.\n * To automatically cast to an integer, use `indexUint`.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The 32 byte result\n */\n function index(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (bytes32 result) {\n if (_bytes == 0) {\n return bytes32(0);\n }\n if (_index + _bytes \u003e len(memView)) {\n revert(indexErrOverrun(loc(memView), len(memView), _index, uint256(_bytes)));\n }\n require(_bytes \u003c= 32, \"TypedMemView/index - Attempted to index more than 32 bytes\");\n\n uint8 bitLength;\n unchecked {\n bitLength = _bytes * 8;\n }\n uint256 _loc = loc(memView);\n uint256 _mask = leftMask(bitLength);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n result := and(mload(add(_loc, _index)), _mask)\n }\n }\n\n /**\n * @notice Parse an unsigned integer from the view at `_index`.\n * @dev Requires that the view have \u003e= `_bytes` bytes following that index.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return uint256(index(memView, _index, _bytes)) \u003e\u003e ((32 - _bytes) * 8);\n }\n\n /**\n * @notice Parse an unsigned integer from LE bytes.\n * @param memView The view\n * @param _index The index\n * @param _bytes The bytes\n * @return result - The unsigned integer\n */\n function indexLEUint(\n bytes29 memView,\n uint256 _index,\n uint8 _bytes\n ) internal pure returns (uint256 result) {\n return reverseUint256(uint256(index(memView, _index, _bytes)));\n }\n\n /**\n * @notice Parse an address from the view at `_index`. Requires that the view have \u003e= 20 bytes\n * following that index.\n * @param memView The view\n * @param _index The index\n * @return address - The address\n */\n function indexAddress(bytes29 memView, uint256 _index) internal pure returns (address) {\n return address(uint160(indexUint(memView, _index, 20)));\n }\n\n /**\n * @notice Return the keccak256 hash of the underlying memory\n * @param memView The view\n * @return digest - The keccak256 hash of the underlying memory\n */\n function keccak(bytes29 memView) internal pure returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n digest := keccak256(_loc, _len)\n }\n }\n\n /**\n * @notice Return the sha2 digest of the underlying memory.\n * @dev We explicitly deallocate memory afterwards.\n * @param memView The view\n * @return digest - The sha2 hash of the underlying memory\n */\n function sha2(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Implements bitcoin's hash160 (rmd160(sha2()))\n * @param memView The pre-image\n * @return digest - the Digest\n */\n function hash160(bytes29 memView) internal view returns (bytes20 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2\n pop(staticcall(gas(), 3, ptr, 0x20, ptr, 0x20)) // rmd160\n digest := mload(add(ptr, 0xc)) // return value is 0-prefixed.\n }\n }\n\n /**\n * @notice Implements bitcoin's hash256 (double sha2)\n * @param memView A view of the preimage\n * @return digest - the Digest\n */\n function hash256(bytes29 memView) internal view returns (bytes32 digest) {\n uint256 _loc = loc(memView);\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n pop(staticcall(gas(), 2, _loc, _len, ptr, 0x20)) // sha2 #1\n pop(staticcall(gas(), 2, ptr, 0x20, ptr, 0x20)) // sha2 #2\n digest := mload(ptr)\n }\n }\n\n /**\n * @notice Return true if the underlying memory is equal. Else false.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the underlying memory is equal\n */\n function untypedEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return\n (loc(left) == loc(right) \u0026\u0026 len(left) == len(right)) || keccak(left) == keccak(right);\n }\n\n /**\n * @notice Return false if the underlying memory is equal. Else true.\n * @param left The first view\n * @param right The second view\n * @return bool - False if the underlying memory is equal\n */\n function untypedNotEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !untypedEqual(left, right);\n }\n\n /**\n * @notice Compares type equality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are the same\n */\n function equal(bytes29 left, bytes29 right) internal pure returns (bool) {\n return left == right || (typeOf(left) == typeOf(right) \u0026\u0026 keccak(left) == keccak(right));\n }\n\n /**\n * @notice Compares type inequality.\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param left The first view\n * @param right The second view\n * @return bool - True if the types are not the same\n */\n function notEqual(bytes29 left, bytes29 right) internal pure returns (bool) {\n return !equal(left, right);\n }\n\n /**\n * @notice Copy the view to a location, return an unsafe memory reference\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memView The view\n * @param _newLoc The new location\n * @return written - the unsafe memory reference\n */\n function unsafeCopyTo(bytes29 memView, uint256 _newLoc) private view returns (bytes29 written) {\n require(notNull(memView), \"TypedMemView/copyTo - Null pointer deref\");\n require(isValid(memView), \"TypedMemView/copyTo - Invalid pointer deref\");\n uint256 _len = len(memView);\n uint256 _oldLoc = loc(memView);\n\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _newLoc) {\n revert(0x60, 0x20) // empty revert message\n }\n\n // use the identity precompile to copy\n // guaranteed not to fail, so pop the success\n pop(staticcall(gas(), 4, _oldLoc, _len, _newLoc, _len))\n }\n\n written = unsafeBuildUnchecked(typeOf(memView), _newLoc, _len);\n }\n\n /**\n * @notice Copies the referenced memory to a new loc in memory, returning a `bytes` pointing to\n * the new memory\n * @dev Shortcuts if the pointers are identical, otherwise compares type and digest.\n * @param memView The view\n * @return ret - The view pointing to the new memory\n */\n function clone(bytes29 memView) internal view returns (bytes memory ret) {\n uint256 ptr;\n uint256 _len = len(memView);\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n ret := ptr\n }\n unchecked {\n unsafeCopyTo(memView, ptr + 0x20);\n }\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n mstore(0x40, add(add(ptr, _len), 0x20)) // write new unused pointer\n mstore(ptr, _len) // write len of new array (in bytes)\n }\n }\n\n /**\n * @notice Join the views in memory, return an unsafe reference to the memory.\n * @dev Super Dangerous direct memory access.\n *\n * This reference can be overwritten if anything else modifies memory (!!!).\n * As such it MUST be consumed IMMEDIATELY.\n * This function is private to prevent unsafe usage by callers.\n * @param memViews The views\n * @return unsafeView - The conjoined view pointing to the new memory\n */\n function unsafeJoin(bytes29[] memory memViews, uint256 _location)\n private\n view\n returns (bytes29 unsafeView)\n {\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n let ptr := mload(0x40)\n // revert if we're writing in occupied memory\n if gt(ptr, _location) {\n revert(0x60, 0x20) // empty revert message\n }\n }\n\n uint256 _offset = 0;\n for (uint256 i = 0; i \u003c memViews.length; i++) {\n bytes29 memView = memViews[i];\n unchecked {\n unsafeCopyTo(memView, _location + _offset);\n _offset += len(memView);\n }\n }\n unsafeView = unsafeBuildUnchecked(0, _location, _offset);\n }\n\n /**\n * @notice Produce the keccak256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The keccak256 digest\n */\n function joinKeccak(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return keccak(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice Produce the sha256 digest of the concatenated contents of multiple views.\n * @param memViews The views\n * @return bytes32 - The sha256 digest\n */\n function joinSha2(bytes29[] memory memViews) internal view returns (bytes32) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n return sha2(unsafeJoin(memViews, ptr));\n }\n\n /**\n * @notice copies all views, joins them into a new bytearray.\n * @param memViews The views\n * @return ret - The new byte array\n */\n function join(bytes29[] memory memViews) internal view returns (bytes memory ret) {\n uint256 ptr;\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n ptr := mload(0x40) // load unused memory pointer\n }\n\n bytes29 _newView;\n unchecked {\n _newView = unsafeJoin(memViews, ptr + 0x20);\n }\n uint256 _written = len(_newView);\n uint256 _footprint = footprint(_newView);\n\n assembly {\n // solhint-disable-previous-line no-inline-assembly\n // store the legnth\n mstore(ptr, _written)\n // new pointer is old + 0x20 + the footprint of the body\n mstore(0x40, add(add(ptr, _footprint), 0x20))\n ret := ptr\n }\n }\n}\n\nlibrary Attestation {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev AttestationData memory layout\n * [000 .. 004): homeDomain uint32 4 bytes\n * [004 .. 008): nonce uint32 4 bytes\n * [008 .. 040): root bytes32 32 bytes\n *\n * Attestation memory layout\n * [000 .. 040): data bytes 40 bytes (see above)\n * [040 .. END): signature bytes ?? bytes (64/65 bytes)\n */\n\n uint256 internal constant OFFSET_HOME_DOMAIN = 0;\n uint256 internal constant OFFSET_NONCE = 4;\n uint256 internal constant OFFSET_ROOT = 8;\n uint256 internal constant ATTESTATION_DATA_LENGTH = 40;\n uint256 internal constant OFFSET_SIGNATURE = ATTESTATION_DATA_LENGTH;\n\n /**\n * @notice Returns formatted Attestation with provided fields\n * @param _data Attestation Data (see above)\n * @param _signature Notary's signature on `_data`\n * @return Formatted attestation\n **/\n function formatAttestation(bytes memory _data, bytes memory _signature)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(_data, _signature);\n }\n\n /**\n * @notice Returns formatted Attestation Data with provided fields\n * @param _domain Domain of Home's chain\n * @param _root New merkle root\n * @param _nonce Nonce of the merkle root\n * @return Formatted data\n **/\n function formatAttestationData(\n uint32 _domain,\n uint32 _nonce,\n bytes32 _root\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(_domain, _nonce, _root);\n }\n\n /**\n * @notice Checks that message is an Attestation, by checking its length\n */\n function isAttestation(bytes29 _view) internal pure returns (bool) {\n // Should have non-zero length for signature. Signature validity is not checked.\n return _view.len() \u003e ATTESTATION_DATA_LENGTH;\n }\n\n /**\n * @notice Returns domain of chain where the Home contract is deployed\n */\n function attestationDomain(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_HOME_DOMAIN, 4));\n }\n\n /**\n * @notice Returns nonce of Home contract at the time, when `root` was the Merkle root.\n */\n function attestationNonce(bytes29 _view) internal pure returns (uint32) {\n return uint32(_view.indexUint(OFFSET_NONCE, 4));\n }\n\n /**\n * @notice Returns a historical Merkle root from the Home contract\n */\n function attestationRoot(bytes29 _view) internal pure returns (bytes32) {\n return _view.index(OFFSET_ROOT, 32);\n }\n\n /**\n * @notice Returns Attestation's Data, that is going to be signed by the Notary\n */\n function attestationData(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_HOME_DOMAIN, ATTESTATION_DATA_LENGTH, 0);\n }\n\n /**\n * @notice Returns Notary's signature on AttestationData\n */\n function attestationSignature(bytes29 _view) internal pure returns (bytes29) {\n return _view.slice(OFFSET_SIGNATURE, _view.len() - ATTESTATION_DATA_LENGTH, 0);\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp \u003e\u003e= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i \u003e 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value \u0026 0xf];\n value \u003e\u003e= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n}\n\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs \u0026 bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) \u003e\u003e 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 \u003c s \u003c secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) \u003e 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 \u0026\u0026 v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n\nlibrary Auth {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Recovers signer from data and signature.\n * @param _data Data that was signed\n * @param _signature `_data` signed by `signer`\n * @return signer Address that signed the data\n */\n function recoverSigner(bytes29 _data, bytes memory _signature)\n internal\n pure\n returns (address signer)\n {\n bytes32 digest = _data.keccak();\n digest = ECDSA.toEthSignedMessageHash(digest);\n signer = ECDSA.recover(digest, _signature);\n }\n}\n\nabstract contract AbstractNotaryRegistry {\n using Attestation for bytes29;\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @notice Checks if the passed payload is a valid Attestation message,\n * if the signature is valid and if the signer is an authorized notary.\n * @param _attestation Attestation of Home merkle root. Needs to be valid, revert otherwise.\n * @return _updater Notary that signed the Attestation\n * @return _view Memory view on attestation\n */\n function _checkNotaryAuth(bytes memory _attestation)\n internal\n view\n returns (address _updater, bytes29 _view)\n {\n _view = _attestation.ref(0);\n require(_view.isAttestation(), \"Not an attestation\");\n _updater = Auth.recoverSigner(\n _view.attestationData(),\n _view.attestationSignature().clone()\n );\n require(_isNotary(_view.attestationDomain(), _updater), \"Signer is not a notary\");\n }\n\n function _isNotary(uint32 _homeDomain, address _notary) internal view virtual returns (bool);\n}\n\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 =\u003e uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n assembly {\n result := store\n }\n\n return result;\n }\n}\n\ncontract DomainNotaryRegistry is AbstractNotaryRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 private immutable trackedDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal notaries;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event DomainNotaryAdded(address notary);\n\n event DomainNotaryRemoved(address notary);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _trackedDomain) {\n trackedDomain = _trackedDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allNotaries() external view returns (address[] memory) {\n return notaries.values();\n }\n\n function getNotary(uint256 _index) external view returns (address) {\n return notaries.at(_index);\n }\n\n function notariesAmount() external view returns (uint256) {\n return notaries.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addNotary(address _notary) internal returns (bool notaryAdded) {\n notaryAdded = notaries.add(_notary);\n if (notaryAdded) {\n emit DomainNotaryAdded(_notary);\n }\n }\n\n function _removeNotary(address _notary) internal returns (bool notaryRemoved) {\n notaryRemoved = notaries.remove(_notary);\n if (notaryRemoved) {\n emit DomainNotaryRemoved(_notary);\n }\n }\n\n function _isNotary(uint32 _domain, address _notary) internal view override returns (bool) {\n require(_domain == trackedDomain, \"Wrong domain\");\n return notaries.contains(_notary);\n }\n}\n\nabstract contract AbstractGuardRegistry {\n function _checkGuardAuth(bytes memory _report)\n internal\n view\n returns (address _guard, bytes29 _data)\n {\n // TODO: check if _report is valid, once guard message standard is finalized\n }\n\n function _isGuard(address _guard) internal view virtual returns (bool);\n}\n\ncontract GuardRegistry is AbstractGuardRegistry {\n using EnumerableSet for EnumerableSet.AddressSet;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n EnumerableSet.AddressSet internal guards;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ UPGRADE GAP ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n // solhint-disable-next-line var-name-mixedcase\n uint256[49] private __GAP;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ EVENTS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n event GuardAdded(address guard);\n\n event GuardRemoved(address guard);\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ VIEWS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function allGuards() external view returns (address[] memory) {\n return guards.values();\n }\n\n function getGuard(uint256 _index) external view returns (address) {\n return guards.at(_index);\n }\n\n function guardsAmount() external view returns (uint256) {\n return guards.length();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _addGuard(address _guard) internal returns (bool guardAdded) {\n guardAdded = guards.add(_guard);\n if (guardAdded) {\n emit GuardAdded(_guard);\n }\n }\n\n function _removeGuard(address _guard) internal returns (bool guardRemoved) {\n guardRemoved = guards.remove(_guard);\n if (guardRemoved) {\n emit GuardRemoved(_guard);\n }\n }\n\n function _isGuard(address _guard) internal view override returns (bool) {\n return guards.contains(_guard);\n }\n}\n\nlibrary MerkleLib {\n uint256 internal constant TREE_DEPTH = 32;\n uint256 internal constant MAX_LEAVES = 2**TREE_DEPTH - 1;\n\n /**\n * @notice Struct representing incremental merkle tree. Contains current\n * branch and the number of inserted leaves in the tree.\n **/\n struct Tree {\n bytes32[TREE_DEPTH] branch;\n uint256 count;\n }\n\n /**\n * @notice Inserts `_node` into merkle tree\n * @dev Reverts if tree is full\n * @param _node Element to insert into tree\n **/\n function insert(Tree storage _tree, bytes32 _node) internal {\n uint256 size = _tree.count;\n require(size \u003c MAX_LEAVES, \"merkle tree full\");\n\n unchecked {\n ++size;\n }\n _tree.count = size;\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n if ((size \u0026 1) == 1) {\n _tree.branch[i] = _node;\n return;\n }\n _node = keccak256(abi.encodePacked(_tree.branch[i], _node));\n size \u003e\u003e= 1;\n unchecked {\n ++i;\n }\n }\n // As the loop should always end prematurely with the `return` statement,\n // this code should be unreachable. We assert `false` just to be safe.\n assert(false);\n }\n\n /**\n * @notice Calculates and returns`_tree`'s current root given array of zero\n * hashes\n * @param _zeroes Array of zero hashes\n * @return _current Calculated root of `_tree`\n **/\n function rootWithCtx(Tree storage _tree, bytes32[TREE_DEPTH] memory _zeroes)\n internal\n view\n returns (bytes32 _current)\n {\n uint256 _index = _tree.count;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_tree.branch[i], _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _zeroes[i]));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /// @notice Calculates and returns`_tree`'s current root\n function root(Tree storage _tree) internal view returns (bytes32) {\n return rootWithCtx(_tree, zeroHashes());\n }\n\n /// @notice Returns array of TREE_DEPTH zero hashes\n /// @return _zeroes Array of TREE_DEPTH zero hashes\n function zeroHashes() internal pure returns (bytes32[TREE_DEPTH] memory _zeroes) {\n _zeroes[0] = Z_0;\n _zeroes[1] = Z_1;\n _zeroes[2] = Z_2;\n _zeroes[3] = Z_3;\n _zeroes[4] = Z_4;\n _zeroes[5] = Z_5;\n _zeroes[6] = Z_6;\n _zeroes[7] = Z_7;\n _zeroes[8] = Z_8;\n _zeroes[9] = Z_9;\n _zeroes[10] = Z_10;\n _zeroes[11] = Z_11;\n _zeroes[12] = Z_12;\n _zeroes[13] = Z_13;\n _zeroes[14] = Z_14;\n _zeroes[15] = Z_15;\n _zeroes[16] = Z_16;\n _zeroes[17] = Z_17;\n _zeroes[18] = Z_18;\n _zeroes[19] = Z_19;\n _zeroes[20] = Z_20;\n _zeroes[21] = Z_21;\n _zeroes[22] = Z_22;\n _zeroes[23] = Z_23;\n _zeroes[24] = Z_24;\n _zeroes[25] = Z_25;\n _zeroes[26] = Z_26;\n _zeroes[27] = Z_27;\n _zeroes[28] = Z_28;\n _zeroes[29] = Z_29;\n _zeroes[30] = Z_30;\n _zeroes[31] = Z_31;\n }\n\n /**\n * @notice Calculates and returns the merkle root for the given leaf\n * `_item`, a merkle branch, and the index of `_item` in the tree.\n * @param _item Merkle leaf\n * @param _branch Merkle proof\n * @param _index Index of `_item` in tree\n * @return _current Calculated merkle root\n **/\n function branchRoot(\n bytes32 _item,\n bytes32[TREE_DEPTH] memory _branch,\n uint256 _index\n ) internal pure returns (bytes32 _current) {\n _current = _item;\n\n for (uint256 i = 0; i \u003c TREE_DEPTH; ) {\n uint256 _ithBit = (_index \u003e\u003e i) \u0026 0x01;\n bytes32 _next = _branch[i];\n if (_ithBit == 1) {\n _current = keccak256(abi.encodePacked(_next, _current));\n } else {\n _current = keccak256(abi.encodePacked(_current, _next));\n }\n unchecked {\n ++i;\n }\n }\n }\n\n // keccak256 zero hashes\n bytes32 internal constant Z_0 =\n hex\"0000000000000000000000000000000000000000000000000000000000000000\";\n bytes32 internal constant Z_1 =\n hex\"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5\";\n bytes32 internal constant Z_2 =\n hex\"b4c11951957c6f8f642c4af61cd6b24640fec6dc7fc607ee8206a99e92410d30\";\n bytes32 internal constant Z_3 =\n hex\"21ddb9a356815c3fac1026b6dec5df3124afbadb485c9ba5a3e3398a04b7ba85\";\n bytes32 internal constant Z_4 =\n hex\"e58769b32a1beaf1ea27375a44095a0d1fb664ce2dd358e7fcbfb78c26a19344\";\n bytes32 internal constant Z_5 =\n hex\"0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d\";\n bytes32 internal constant Z_6 =\n hex\"887c22bd8750d34016ac3c66b5ff102dacdd73f6b014e710b51e8022af9a1968\";\n bytes32 internal constant Z_7 =\n hex\"ffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83\";\n bytes32 internal constant Z_8 =\n hex\"9867cc5f7f196b93bae1e27e6320742445d290f2263827498b54fec539f756af\";\n bytes32 internal constant Z_9 =\n hex\"cefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0\";\n bytes32 internal constant Z_10 =\n hex\"f9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5\";\n bytes32 internal constant Z_11 =\n hex\"f8b13a49e282f609c317a833fb8d976d11517c571d1221a265d25af778ecf892\";\n bytes32 internal constant Z_12 =\n hex\"3490c6ceeb450aecdc82e28293031d10c7d73bf85e57bf041a97360aa2c5d99c\";\n bytes32 internal constant Z_13 =\n hex\"c1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb\";\n bytes32 internal constant Z_14 =\n hex\"5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc\";\n bytes32 internal constant Z_15 =\n hex\"da7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2\";\n bytes32 internal constant Z_16 =\n hex\"2733e50f526ec2fa19a22b31e8ed50f23cd1fdf94c9154ed3a7609a2f1ff981f\";\n bytes32 internal constant Z_17 =\n hex\"e1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a\";\n bytes32 internal constant Z_18 =\n hex\"5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0\";\n bytes32 internal constant Z_19 =\n hex\"b46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0\";\n bytes32 internal constant Z_20 =\n hex\"c65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2\";\n bytes32 internal constant Z_21 =\n hex\"f4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9\";\n bytes32 internal constant Z_22 =\n hex\"5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377\";\n bytes32 internal constant Z_23 =\n hex\"4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652\";\n bytes32 internal constant Z_24 =\n hex\"cdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef\";\n bytes32 internal constant Z_25 =\n hex\"0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d\";\n bytes32 internal constant Z_26 =\n hex\"b8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0\";\n bytes32 internal constant Z_27 =\n hex\"838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e\";\n bytes32 internal constant Z_28 =\n hex\"662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e\";\n bytes32 internal constant Z_29 =\n hex\"388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322\";\n bytes32 internal constant Z_30 =\n hex\"93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735\";\n bytes32 internal constant Z_31 =\n hex\"8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9\";\n}\n\n//\n\nlibrary TypeCasts {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n function coerceBytes32(string memory _s) internal pure returns (bytes32 _b) {\n _b = bytes(_s).ref(0).index(0, uint8(bytes(_s).length));\n }\n\n // treat it as a null-terminated string of max 32 bytes\n function coerceString(bytes32 _buf) internal pure returns (string memory _newStr) {\n uint8 _slen = 0;\n while (_slen \u003c 32 \u0026\u0026 _buf[_slen] != 0) {\n _slen++;\n }\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n _newStr := mload(0x40)\n mstore(0x40, add(_newStr, 0x40)) // may end up with extra\n mstore(_newStr, _slen)\n mstore(add(_newStr, 0x20), _buf)\n }\n }\n\n // alignment preserving cast\n function addressToBytes32(address _addr) internal pure returns (bytes32) {\n return bytes32(uint256(uint160(_addr)));\n }\n\n // alignment preserving cast\n function bytes32ToAddress(bytes32 _buf) internal pure returns (address) {\n return address(uint160(uint256(_buf)));\n }\n}\n\nlibrary Header {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant HEADER_VERSION = 1;\n\n /**\n * @dev Header memory layout\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 006): originDomain uint32 4 bytes\n * [006 .. 038): sender bytes32 32 bytes\n * [038 .. 042): nonce uint32 4 bytes\n * [042 .. 046): destinationDomain uint32 4 bytes\n * [046 .. 078): recipient bytes32 32 bytes\n * [078 .. 082): optimisticSeconds uint32 4 bytes\n */\n\n uint256 internal constant OFFSET_ORIGIN = 2;\n uint256 internal constant OFFSET_SENDER = 6;\n uint256 internal constant OFFSET_NONCE = 38;\n uint256 internal constant OFFSET_DESTINATION = 42;\n uint256 internal constant OFFSET_RECIPIENT = 46;\n uint256 internal constant OFFSET_OPTIMISTIC_SECONDS = 78;\n\n modifier onlyHeader(bytes29 _view) {\n _view.assertType(Message.HEADER_TYPE);\n _;\n }\n\n function formatHeader(\n uint32 _originDomain,\n bytes32 _sender,\n uint32 _nonce,\n uint32 _destinationDomain,\n bytes32 _recipient,\n uint32 _optimisticSeconds\n ) internal pure returns (bytes memory) {\n return\n abi.encodePacked(\n HEADER_VERSION,\n _originDomain,\n _sender,\n _nonce,\n _destinationDomain,\n _recipient,\n _optimisticSeconds\n );\n }\n\n function headerView(bytes memory _header) internal pure returns (bytes29) {\n return _header.ref(Message.HEADER_TYPE);\n }\n\n function headerVersion(bytes29 _header) internal pure onlyHeader(_header) returns (uint16) {\n return uint16(_header.indexUint(0, 2));\n }\n\n /// @notice Returns header's origin field\n function origin(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_ORIGIN, 4));\n }\n\n /// @notice Returns header's sender field\n function sender(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_SENDER, 32);\n }\n\n /// @notice Returns header's nonce field\n function nonce(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_NONCE, 4));\n }\n\n /// @notice Returns header's destination field\n function destination(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_DESTINATION, 4));\n }\n\n /// @notice Returns header's recipient field as bytes32\n function recipient(bytes29 _header) internal pure onlyHeader(_header) returns (bytes32) {\n return _header.index(OFFSET_RECIPIENT, 32);\n }\n\n /// @notice Returns header's optimistic seconds field\n function optimisticSeconds(bytes29 _header) internal pure onlyHeader(_header) returns (uint32) {\n return uint32(_header.indexUint(OFFSET_OPTIMISTIC_SECONDS, 4));\n }\n\n /// @notice Returns header's recipient field as an address\n function recipientAddress(bytes29 _header) internal pure returns (address) {\n return TypeCasts.bytes32ToAddress(recipient(_header));\n }\n}\n\nlibrary Message {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n /**\n * @dev This is only updated if the whole message structure is changed,\n * i.e. if a new part is added.\n * If already existing part is changed, the message version does not get bumped.\n */\n uint16 internal constant MESSAGE_VERSION = 1;\n\n /// @dev Parts.Last is used only for marking the last element of the enum\n enum Parts {\n Version,\n Header,\n Tips,\n Body,\n Last\n }\n\n uint40 internal constant MESSAGE_TYPE = 1337;\n uint40 internal constant HEADER_TYPE = uint40(Parts.Header);\n uint40 internal constant TIPS_TYPE = uint40(Parts.Tips);\n uint40 internal constant BODY_TYPE = uint40(Parts.Body);\n\n modifier onlyMessage(bytes29 _view) {\n _view.assertType(MESSAGE_TYPE);\n _;\n }\n\n /**\n * @dev Message memory layout\n * All offsets are stored for backwards compatibility\n * [000 .. 002): version uint16 2 bytes\n * [002 .. 004): header offset = 8 uint16 2 bytes\n * [004 .. 006): tips offset (AAA) uint16 2 bytes\n * [006 .. 008): body offset (BBB) uint16 2 bytes\n * [008 .. AAA): header bytes ? bytes\n * [AAA .. BBB): tips bytes ? bytes\n * [BBB .. CCC): body bytes ? bytes\n */\n\n /// @dev How much bytes is used for storing the version, or a single offset value\n uint8 internal constant TWO_BYTES = 2;\n /// @dev This value reflects the header offset in the latest message version\n uint16 internal constant HEADER_OFFSET = TWO_BYTES * uint8(Parts.Last);\n\n /**\n * @notice Returns formatted (packed) message with provided fields\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Formatted message\n **/\n function formatMessage(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes memory) {\n // Version + Offsets + Header + Tips are supposed to fit within 65535 bytes\n uint16 tipsOffset = HEADER_OFFSET + uint16(_header.length);\n uint16 bodyOffset = tipsOffset + uint16(_tips.length);\n return\n abi.encodePacked(\n MESSAGE_VERSION,\n HEADER_OFFSET,\n tipsOffset,\n bodyOffset,\n _header,\n _tips,\n _messageBody\n );\n }\n\n /**\n * @notice Returns leaf of formatted message with provided fields.\n * @param _header Formatted header\n * @param _messageBody Raw bytes of message body\n * @return Leaf (hash) of formatted message\n **/\n function messageHash(\n bytes memory _header,\n bytes memory _tips,\n bytes memory _messageBody\n ) internal pure returns (bytes32) {\n return keccak256(formatMessage(_header, _tips, _messageBody));\n }\n\n function messageView(bytes memory _message) internal pure returns (bytes29) {\n return _message.ref(MESSAGE_TYPE);\n }\n\n /// @notice Returns message's header field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function header(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Header),\n _loadOffset(_message, Parts.Tips),\n HEADER_TYPE\n );\n }\n\n /// @notice Returns message's tips field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function tips(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return\n _between(\n _message,\n _loadOffset(_message, Parts.Tips),\n _loadOffset(_message, Parts.Body),\n TIPS_TYPE\n );\n }\n\n /// @notice Returns message's body field as bytes29 (refer to TypedMemView library for details on bytes29 type)\n function body(bytes29 _message) internal pure onlyMessage(_message) returns (bytes29) {\n return _between(_message, _loadOffset(_message, Parts.Body), _message.len(), BODY_TYPE);\n }\n\n /// @notice Returns leaf of the formatted message.\n function leaf(bytes29 _message) internal pure onlyMessage(_message) returns (bytes32) {\n // TODO: do we actually need this?\n return _message.keccak();\n }\n\n function _between(\n bytes29 _message,\n uint256 _from,\n uint256 _to,\n uint40 _newType\n ) private pure returns (bytes29) {\n return _message.slice(_from, _to - _from, _newType);\n }\n\n /// @notice Loads offset for a given part of the message\n function _loadOffset(bytes29 _message, Parts _part) private pure returns (uint256) {\n return _message.indexUint(uint256(_part) * TWO_BYTES, TWO_BYTES);\n }\n}\n\nlibrary Tips {\n using TypedMemView for bytes;\n using TypedMemView for bytes29;\n\n uint16 internal constant TIPS_VERSION = 1;\n\n /**\n * @dev Tips memory layout\n * [000 .. 002): version uint16\t 2 bytes\n * [002 .. 014): updaterTip uint96\t12 bytes\n * [014 .. 026): relayerTip uint96\t12 bytes\n * [026 .. 038): proverTip uint96\t12 bytes\n * [038 .. 050): processorTip uint96\t12 bytes\n */\n\n uint256 internal constant OFFSET_UPDATER = 2;\n uint256 internal constant OFFSET_RELAYER = 14;\n uint256 internal constant OFFSET_PROVER = 26;\n uint256 internal constant OFFSET_PROCESSOR = 38;\n\n modifier onlyTips(bytes29 _view) {\n _view.assertType(Message.TIPS_TYPE);\n _;\n }\n\n /**\n * @notice Returns formatted (packed) tips with provided fields\n * @param _updaterTip Tip for the Updater\n * @param _relayerTip Tip for the Relayer\n * @param _proverTip Tip for the Prover\n * @param _processorTip Tip for the Processor\n * @return Formatted tips\n **/\n function formatTips(\n uint96 _updaterTip,\n uint96 _relayerTip,\n uint96 _proverTip,\n uint96 _processorTip\n ) internal pure returns (bytes memory) {\n return abi.encodePacked(TIPS_VERSION, _updaterTip, _relayerTip, _proverTip, _processorTip);\n }\n\n /**\n * @notice Returns formatted empty tips\n * @return Formatted tips\n **/\n function emptyTips() internal pure returns (bytes memory) {\n return formatTips(0, 0, 0, 0);\n }\n\n /// @notice Returns view for the formatted tips\n /// @dev Providing anything other than formatted tips will lead to unexpected behavior\n function tipsView(bytes memory _tips) internal pure returns (bytes29) {\n return _tips.ref(Message.TIPS_TYPE);\n }\n\n /// @notice Returns version of formatted tips\n function tipsVersion(bytes29 _tips) internal pure onlyTips(_tips) returns (uint16) {\n return uint16(_tips.indexUint(0, 2));\n }\n\n /// @notice Returns updaterTip field\n function updaterTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_UPDATER, 12));\n }\n\n /// @notice Returns relayerTip field\n function relayerTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_RELAYER, 12));\n }\n\n /// @notice Returns proverTip field\n function proverTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROVER, 12));\n }\n\n /// @notice Returns processorTip field\n function processorTip(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return uint32(_tips.indexUint(OFFSET_PROCESSOR, 12));\n }\n\n function totalTips(bytes29 _tips) internal pure onlyTips(_tips) returns (uint96) {\n return updaterTip(_tips) + relayerTip(_tips) + proverTip(_tips) + processorTip(_tips);\n }\n}\n\nlibrary SystemMessage {\n using TypedMemView for bytes29;\n\n enum SystemMessageType {\n None,\n Call,\n Adjust\n }\n\n /**\n * @dev Custom address, used for receiving and sending system messages.\n * Home is supposed to dispatch messages from SystemMessenger as if they were sent by this address.\n * ReplicaManager is supposed to reroute messages for this address to SystemMessenger.\n * Note: all bits except for lower 20 bytes are set to 1.\n * Note: TypeCasts.bytes32ToAddress(SYSTEM_SENDER) = address(0)\n */\n bytes32 internal constant SYSTEM_SENDER = bytes32(type(uint256).max \u003c\u003c 160);\n\n /**\n * @dev SystemMessage memory layout\n * [000 .. 001): messageType uint8 1 bytes\n * [001 .. END]: messageBody bytes ? bytes\n */\n\n uint256 internal constant OFFSET_BODY = 1;\n\n /**\n * @dev SystemMessageType.Call memory layout\n * [000 .. 001): recipient uint8 1 bytes\n * [001 .. END]: payload bytes ? bytes\n */\n\n uint256 internal constant OFFSET_CALL_PAYLOAD = 1;\n\n // TODO: memory layout + setter/getters for SystemMessageType.Adjust\n\n modifier onlyType(SystemMessageType _type, bytes29 _view) {\n _view.assertType(uint40(_type));\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ FORMATTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function formatSystemMessage(SystemMessageType _messageType, bytes memory _messageBody)\n internal\n pure\n returns (bytes memory)\n {\n return abi.encodePacked(uint8(_messageType), _messageBody);\n }\n\n function formatCall(uint8 _recipientType, bytes memory _payload)\n internal\n pure\n returns (bytes memory)\n {\n return\n formatSystemMessage(SystemMessageType.Call, abi.encodePacked(_recipientType, _payload));\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM MESSAGE GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function systemMessage(bytes29 _message)\n internal\n pure\n returns (SystemMessageType _messageType, bytes29 _messageView)\n {\n _messageType = SystemMessageType(_message.indexUint(0, 1));\n _messageView = _message.slice(\n OFFSET_BODY,\n _message.len() - OFFSET_BODY,\n uint40(_messageType)\n );\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ SYSTEM_MESSAGE_TYPE.CALL GETTERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function callRecipient(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (uint8)\n {\n return uint8(_call.indexUint(0, 1));\n }\n\n function callPayload(bytes29 _call)\n internal\n pure\n onlyType(SystemMessageType.Call, _call)\n returns (bytes29)\n {\n return _call.slice(OFFSET_CALL_PAYLOAD, _call.len() - OFFSET_CALL_PAYLOAD, 0);\n }\n}\n\ninterface ISystemMessenger {\n /// @dev Potential senders/recipients of a system message\n enum SystemContracts {\n Home,\n ReplicaManager\n }\n\n /**\n * @notice Send System Message to one of the System Contracts on origin chain\n * @dev Note that knowledge of recipient address is not required,\n * routing will be done by SystemMessenger on destination chain.\n * @param _destDomain Domain of destination chain\n * @param _recipient System contract type of the recipient\n * @param _payload Data for calling recipient on destination chain\n */\n function sendSystemMessage(\n uint32 _destDomain,\n SystemContracts _recipient,\n bytes memory _payload\n ) external;\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\n// \n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = _setInitializedVersion(1);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n bool isTopLevelCall = _setInitializedVersion(version);\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(version);\n }\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n _setInitializedVersion(type(uint8).max);\n }\n\n function _setInitializedVersion(uint8 version) private returns (bool) {\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n // of initializers, because in other contexts the contract may have been reentered.\n if (_initializing) {\n require(\n version == 1 \u0026\u0026 !AddressUpgradeable.isContract(address(this)),\n \"Initializable: contract is already initialized\"\n );\n return false;\n } else {\n require(_initialized \u003c version, \"Initializable: contract is already initialized\");\n _initialized = version;\n return true;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n\nabstract contract SystemContract is OwnableUpgradeable {\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ IMMUTABLES ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n uint32 public immutable localDomain;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ STORAGE ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n ISystemMessenger public systemMessenger;\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ CONSTRUCTOR ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n constructor(uint32 _localDomain) {\n localDomain = _localDomain;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INITIALIZER ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function __SystemContract_initialize() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ MODIFIERS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n /**\n * @dev Modifier for functions that are supposed to be called from\n * System Contracts on other chains.\n */\n modifier onlySystemMessenger() {\n _assertSystemMessenger();\n _;\n }\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ OWNER ONLY ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function setSystemMessenger(ISystemMessenger _systemMessenger) external onlyOwner {\n systemMessenger = _systemMessenger;\n }\n\n /**\n * @dev Should be impossible to renounce ownership;\n * we override OpenZeppelin OwnableUpgradeable's\n * implementation of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {} //solhint-disable-line no-empty-blocks\n\n /*╔══════════════════════════════════════════════════════════════════════╗*\\\n ▏*║ INTERNAL FUNCTIONS ║*▕\n \\*╚══════════════════════════════════════════════════════════════════════╝*/\n\n function _assertSystemMessenger() internal view {\n require(msg.sender == address(systemMessenger), \"!systemMessenger\");\n }\n}\n\ncontract MerkleTreeManager {\n // ============ Libraries ============\n\n using MerkleLib for MerkleLib.Tree;\n MerkleLib.Tree public tree;\n bytes32[] public historicalRoots;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[48] private __GAP;\n\n // ============ Public Functions ============\n\n /**\n * @notice Calculates and returns tree's current root\n */\n function root() public view returns (bytes32) {\n return tree.root();\n }\n\n /**\n * @notice Returns the number of inserted leaves in the tree (current index)\n */\n function count() public view returns (uint256) {\n return tree.count;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Inserts _hash into the Merkle tree and stores the new merkle root.\n */\n function _insertHash(bytes32 _hash) internal {\n tree.insert(_hash);\n historicalRoots.push(tree.root());\n }\n}\n\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length \u003e 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance \u003e= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance \u003e= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length \u003e 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n\ncontract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegistry, GuardRegistry {\n // ============ Libraries ============\n\n using Attestation for bytes29;\n using MerkleLib for MerkleLib.Tree;\n\n using Tips for bytes;\n using Tips for bytes29;\n\n // ============ Enums ============\n\n // States:\n // 0 - UnInitialized - before initialize function is called\n // note: the contract is initialized at deploy time, so it should never be in this state\n // 1 - Active - as long as the contract has not become fraudulent\n // 2 - Failed - after a valid fraud proof has been submitted;\n // contract will no longer accept updates or new messages\n enum States {\n UnInitialized,\n Active,\n Failed\n }\n\n // ============ Constants ============\n\n // Maximum bytes per message = 2 KiB\n // (somewhat arbitrarily set to begin)\n uint256 public constant MAX_MESSAGE_BODY_BYTES = 2 * 2**10;\n\n // ============ Public Storage Variables ============\n\n // domain =\u003e next available nonce for the domain\n uint32 public nonce;\n // contract responsible for Updater bonding, slashing and rotation\n IUpdaterManager public updaterManager;\n // Current state of contract\n States public state;\n\n // ============ Upgrade Gap ============\n\n // gap for upgrade safety\n uint256[47] private __GAP;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new message is dispatched via Nomad\n * @param messageHash Hash of message; the leaf inserted to the Merkle tree\n * for the message\n * @param leafIndex Index of message's leaf in merkle tree\n * @param destinationAndNonce Destination and destination-specific\n * nonce combined in single field ((destination \u003c\u003c 32) \u0026 nonce)\n * @param tips Tips paid for the remote off-chain agents\n * @param message Raw bytes of message\n */\n event Dispatch(\n bytes32 indexed messageHash,\n uint256 indexed leafIndex,\n uint64 indexed destinationAndNonce,\n bytes tips,\n bytes message\n );\n\n /**\n * @notice Emitted when proof of an improper attestation is submitted,\n * which sets the contract to FAILED state\n * @param updater Updater who signed improper attestation\n * @param attestation Attestation data and signature\n */\n event ImproperAttestation(address updater, bytes attestation);\n\n /**\n * @notice Emitted when the Updater is slashed\n * (should be paired with ImproperUpdater or DoubleUpdate event)\n * @param updater The address of the updater\n * @param reporter The address of the entity that reported the updater misbehavior\n */\n event UpdaterSlashed(address indexed updater, address indexed reporter);\n\n /**\n * @notice Emitted when the UpdaterManager contract is changed\n * @param updaterManager The address of the new updaterManager\n */\n event NewUpdaterManager(address updaterManager);\n\n // ============ Constructor ============\n\n constructor(uint32 _localDomain)\n SystemContract(_localDomain)\n DomainNotaryRegistry(_localDomain)\n {} // solhint-disable-line no-empty-blocks\n\n // ============ Initializer ============\n\n function initialize(IUpdaterManager _updaterManager) public initializer {\n __SystemContract_initialize();\n _setUpdaterManager(_updaterManager);\n _addNotary(updaterManager.updater());\n state = States.Active;\n // insert a historical root so nonces start at 1 rather then 0\n historicalRoots.push(bytes32(\"\"));\n }\n\n // ============ Modifiers ============\n\n /**\n * @notice Ensures that function is called by the UpdaterManager contract\n */\n modifier onlyUpdaterManager() {\n require(msg.sender == address(updaterManager), \"!updaterManager\");\n _;\n }\n\n /**\n * @notice Ensures that contract state != FAILED when the function is called\n */\n modifier notFailed() {\n require(state != States.Failed, \"failed state\");\n _;\n }\n\n // ============ External: Updater \u0026 UpdaterManager Configuration ============\n\n /**\n * @notice Set a new Updater\n * @dev To be set when rotating Updater after Fraud\n * @param _updater the new Updater\n */\n function setUpdater(address _updater) external onlyUpdaterManager {\n // TODO: do this properly\n _addNotary(_updater);\n // set the Home state to Active\n // now that Updater has been rotated\n state = States.Active;\n }\n\n /**\n * @notice Set a new UpdaterManager contract\n * @dev Home(s) will initially be initialized using a trusted UpdaterManager contract;\n * we will progressively decentralize by swapping the trusted contract with a new implementation\n * that implements Updater bonding \u0026 slashing, and rules for Updater selection \u0026 rotation\n * @param _updaterManager the new UpdaterManager contract\n */\n function setUpdaterManager(address _updaterManager) external onlyOwner {\n _setUpdaterManager(IUpdaterManager(_updaterManager));\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Dispatch the message to the destination domain \u0026 recipient\n * @dev Format the message, insert its hash into Merkle tree,\n * enqueue the new Merkle root, and emit `Dispatch` event with message information.\n * @param _destinationDomain Domain of destination chain\n * @param _recipientAddress Address of recipient on destination chain as bytes32\n * @param _messageBody Raw bytes content of message\n */\n function dispatch(\n uint32 _destinationDomain,\n bytes32 _recipientAddress,\n uint32 _optimisticSeconds,\n bytes memory _tips,\n bytes memory _messageBody\n ) external payable notFailed {\n require(_messageBody.length \u003c= MAX_MESSAGE_BODY_BYTES, \"msg too long\");\n require(_tips.tipsView().totalTips() == msg.value, \"!tips\");\n // get the next nonce for the destination domain, then increment it\n nonce = nonce + 1;\n bytes32 _sender = _checkForSystemMessage(_recipientAddress);\n // format the message into packed bytes\n bytes memory _header = Header.formatHeader(\n localDomain,\n _sender,\n nonce,\n _destinationDomain,\n _recipientAddress,\n _optimisticSeconds\n );\n // format the message into packed bytes\n bytes memory _message = Message.formatMessage(_header, _tips, _messageBody);\n // insert the hashed message into the Merkle tree\n bytes32 _messageHash = keccak256(_message);\n // new root is added to the historical roots\n _insertHash(_messageHash);\n // Emit Dispatch event with message information\n // note: leafIndex is count() - 1 since new leaf has already been inserted\n emit Dispatch(\n _messageHash,\n count() - 1,\n _destinationAndNonce(_destinationDomain, nonce),\n _tips,\n _message\n );\n }\n\n /**\n * @notice Suggest an update for the Updater to sign and submit.\n * @dev If no messages have been sent, null bytes returned for both\n * @return _nonce Current nonce\n * @return _root Current merkle root\n */\n function suggestUpdate() external view returns (uint32 _nonce, bytes32 _root) {\n uint256 length = historicalRoots.length;\n if (length != 0) {\n _nonce = uint32(length - 1);\n _root = historicalRoots[_nonce];\n }\n }\n\n // ============ Public Functions ============\n\n /**\n * @notice Check if an Attestation is an Improper Attestation;\n * if so, slash the Updater and set the contract to FAILED state.\n *\n * An Improper Attestation is a (_nonce, _root) update that doesn't correspond with\n * the historical state of Home contract. Either of those needs to be true:\n * - _nonce is higher than current nonce (no root exists for this nonce)\n * - _root is not equal to the historical root of _nonce\n * This would mean that message(s) that were not truly\n * dispatched on Home were falsely included in the signed root.\n *\n * An Improper Attestation will only be accepted as valid by the Replica\n * If an Improper Attestation is attempted on Home,\n * the Updater will be slashed immediately.\n * If an Improper Attestation is submitted to the Replica,\n * it should be relayed to the Home contract using this function\n * in order to slash the Updater with an Improper Attestation.\n *\n * @dev Reverts (and doesn't slash updater) if signature is invalid or\n * update not current\n * @param _attestation Attestation data and signature\n * @return TRUE if update was an Improper Attestation (implying Updater was slashed)\n */\n function improperAttestation(bytes memory _attestation) public notFailed returns (bool) {\n // This will revert if signature is not valid\n (address _notary, bytes29 _view) = _checkNotaryAuth(_attestation);\n uint32 _nonce = _view.attestationNonce();\n bytes32 _root = _view.attestationRoot();\n // Check if nonce is valid, if not =\u003e update is fraud\n if (_nonce \u003c historicalRoots.length) {\n if (_root == historicalRoots[_nonce]) {\n // Signed (nonce, root) update is valid\n return false;\n }\n // Signed root is not the same as the historical one =\u003e update is fraud\n }\n _fail(_notary);\n emit ImproperAttestation(_notary, _attestation);\n return true;\n }\n\n // ============ Internal Functions ============\n\n /**\n * @notice Set the UpdaterManager\n * @param _updaterManager Address of the UpdaterManager\n */\n function _setUpdaterManager(IUpdaterManager _updaterManager) internal {\n require(Address.isContract(address(_updaterManager)), \"!contract updaterManager\");\n updaterManager = IUpdaterManager(_updaterManager);\n emit NewUpdaterManager(address(_updaterManager));\n }\n\n /**\n * @notice Slash the Updater and set contract state to FAILED\n * @dev Called when fraud is proven (Improper Update or Double Update)\n */\n function _fail(address _notary) internal {\n // TODO: remove Failed state\n // set contract to FAILED\n state = States.Failed;\n // slash Updater\n updaterManager.slashUpdater(payable(msg.sender));\n emit UpdaterSlashed(_notary, msg.sender);\n }\n\n /**\n * @notice Internal utility function that combines\n * `_destination` and `_nonce`.\n * @dev Both destination and nonce should be less than 2^32 - 1\n * @param _destination Domain of destination chain\n * @param _nonce Current nonce for given destination chain\n * @return Returns (`_destination` \u003c\u003c 32) \u0026 `_nonce`\n */\n function _destinationAndNonce(uint32 _destination, uint32 _nonce)\n internal\n pure\n returns (uint64)\n {\n return (uint64(_destination) \u003c\u003c 32) | _nonce;\n }\n\n /**\n * @notice Returns \"adjusted\" sender address.\n * @dev By default, \"sender address\" is msg.sender.\n * However, if SystemMessenger sends a message, specifying SYSTEM_SENDER as the recipient,\n * SYSTEM_SENDER is used as \"sender address\" on origin chain.\n * Note that transaction will revert if anyone but SystemMessenger uses SYSTEM_SENDER as the recipient.\n */\n function _checkForSystemMessage(bytes32 _recipientAddress)\n internal\n view\n returns (bytes32 sender)\n {\n if (_recipientAddress != SystemMessage.SYSTEM_SENDER) {\n sender = TypeCasts.addressToBytes32(msg.sender);\n /**\n * @dev Note: SYSTEM_SENDER has highest 12 bytes set,\n * whereas TypeCasts.addressToBytes32 sets only the lowest 20 bytes.\n * Thus, in this branch: sender != SystemMessage.SYSTEM_SENDER\n */\n } else {\n // Check that SystemMessenger specified SYSTEM_SENDER as recipient, revert otherwise.\n _assertSystemMessenger();\n // Adjust \"sender address\" for correct processing on remote chain.\n sender = SystemMessage.SYSTEM_SENDER;\n }\n }\n}\n\n// \n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n\n// \n// ============ Internal Imports ============\n// ============ External Imports ============\n/**\n * @title UpdaterManager\n * @author Illusory Systems Inc.\n * @notice MVP / centralized version of contract\n * that will manage Updater bonding, slashing,\n * selection and rotation\n */\ncontract UpdaterManager is IUpdaterManager, Ownable {\n // ============ Public Storage ============\n\n // address of home contract\n address public home;\n\n // ============ Private Storage ============\n\n // address of the current updater\n address private _updater;\n\n // ============ Events ============\n\n /**\n * @notice Emitted when a new home is set\n * @param home The address of the new home contract\n */\n event NewHome(address home);\n\n /**\n * @notice Emitted when a new updater is set\n * @param updater The address of the new updater\n */\n event NewUpdater(address updater);\n\n /**\n * @notice Emitted when slashUpdater is called\n */\n event FakeSlashed(address reporter);\n\n // ============ Modifiers ============\n\n /**\n * @notice Require that the function is called\n * by the Home contract\n */\n modifier onlyHome() {\n require(msg.sender == home, \"!home\");\n _;\n }\n\n // ============ Constructor ============\n\n constructor(address _updaterAddress) payable Ownable() {\n _updater = _updaterAddress;\n }\n\n // ============ External Functions ============\n\n /**\n * @notice Set the address of the a new home contract\n * @dev only callable by trusted owner\n * @param _home The address of the new home contract\n */\n function setHome(address _home) external onlyOwner {\n require(Address.isContract(_home), \"!contract home\");\n home = _home;\n\n emit NewHome(_home);\n }\n\n /**\n * @notice Set the address of a new updater\n * @dev only callable by trusted owner\n * @param _updaterAddress The address of the new updater\n */\n function setUpdater(address _updaterAddress) external onlyOwner {\n _updater = _updaterAddress;\n Home(home).setUpdater(_updaterAddress);\n emit NewUpdater(_updaterAddress);\n }\n\n /**\n * @notice Slashes the updater\n * @dev Currently does nothing, functionality will be implemented later\n * when updater bonding and rotation are also implemented\n * @param _reporter The address of the entity that reported the updater fraud\n */\n function slashUpdater(address payable _reporter) external override onlyHome {\n emit FakeSlashed(_reporter);\n }\n\n /**\n * @notice Get address of current updater\n * @return the updater address\n */\n function updater() external view override returns (address) {\n return _updater;\n }\n\n /**\n * @dev should be impossible to renounce ownership;\n * we override OpenZeppelin Ownable implementation\n * of renounceOwnership to make it a no-op\n */\n function renounceOwnership() public override onlyOwner {\n // do nothing\n }\n}","language":"Solidity","languageVersion":"0.8.13","compilerVersion":"0.8.13","compilerOptions":"--combined-json bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc,metadata,hashes --optimize --optimize-runs 10000 --allow-paths ., ./, ../","srcMap":"177:60:0:-:0;;;;;;;;;;;;;;;;;;;","srcMapRuntime":"177:60:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;201:33;;233:1;201:33;;;;;186:4:1;174:17;;;156:36;;144:2;129:18;201:33:0;;;;;;","abiDefinition":[{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}],"userDoc":{"kind":"user","methods":{},"version":1},"developerDoc":{"kind":"dev","methods":{},"version":1},"metadata":"{\"compiler\":{\"version\":\"0.8.13+commit.abaa5c0e\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"VERSION\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solidity/UpdaterManager.sol\":\"Version0\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":10000},\"remappings\":[]},\"sources\":{\"solidity/UpdaterManager.sol\":{\"keccak256\":\"0x57c85bd101907d2aa82faa334f2bcf91178263ea8b59d2abbf76be83cc69bfad\",\"urls\":[\"bzz-raw://ed53f43758b66e6b5debfaa56c731f6812e179b79d201876042c8623615e933e\",\"dweb:/ipfs/QmSsu68yzHPccBMNYj92vTbZYTLqs6rQtrzmMX49YLgE9M\"]}},\"version\":1}"},"hashes":{"VERSION()":"ffa1ad74"}}} \ No newline at end of file From f1a684eee162cb8bb64113f8f2964c736e1146fe Mon Sep 17 00:00:00 2001 From: ChiTimesChi <88190723+ChiTimesChi@users.noreply.github.com> Date: Thu, 11 Aug 2022 12:47:31 +0300 Subject: [PATCH 10/10] chore: TODO explained --- packages/contracts/contracts/Home.sol | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/contracts/contracts/Home.sol b/packages/contracts/contracts/Home.sol index 6d167ab55e..3356f398a7 100644 --- a/packages/contracts/contracts/Home.sol +++ b/packages/contracts/contracts/Home.sol @@ -157,7 +157,16 @@ contract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegist * @param _updater the new Updater */ function setUpdater(address _updater) external onlyUpdaterManager { - // TODO: do this properly + /** + * TODO: do this properly + * @dev 1. New Notaries should be added to all System Contracts + * from "secondary" Bonding contracts (global Notary/Guard registry) + * 1a. onlyUpdaterManager -> onlyBondingManager (or w/e the name would be) + * 2. There is supposed to be more than one active Notary + * 2a. setUpdater() -> addNotary() + * 3. No need to reset the `state`, as Home is not supposed + * to be in Failed state in the first place (see _fail() for reasoning). + */ _addNotary(_updater); // set the Home state to Active // now that Updater has been rotated @@ -297,7 +306,14 @@ contract Home is Version0, MerkleTreeManager, SystemContract, DomainNotaryRegist * @dev Called when fraud is proven (Improper Update or Double Update) */ function _fail(address _notary) internal { - // TODO: remove Failed state + /** + * TODO: remove Failed state + * @dev With the asynchronous updates Home is never in the FAILED state. + * It's rather some Replicas might end up with a corrupted merkle state (upon receiving a fraud attestation). + * It's a Replica job to get this conflict fixed, as long as there's more than one active Notary, + * new messages on Home could be verified by an honest Notary. + * Meaning Home should not be halted upon discovering a fraud attestation. + */ // set contract to FAILED state = States.Failed; // slash Updater